我在我的python應用程序中使用了一個模塊,它使用日誌記錄模塊寫了很多消息。最初我在控制檯應用程序中使用它,並且使用控制檯處理程序使日誌輸出顯示在控制檯上非常簡單。現在我使用wxPython開發了我的應用程序的GUI版本,並且我想將所有日誌輸出顯示到自定義控件 - 多行textCtrl。有沒有一種方法可以創建自定義日誌記錄處理程序,以便我可以將所有日誌記錄輸出重定向到那裏,並在任何地方顯示日誌消息/但是我希望 - 在這種情況下,是一個wxPython應用程序。如何使用自定義日誌記錄處理程序將記錄器重定向到wxPython textCtrl?
回答
在你的控制創建處理程序
import wx
import wx.lib.newevent
import logging
# create event type
wxLogEvent, EVT_WX_LOG_EVENT = wx.lib.newevent.NewEvent()
class wxLogHandler(logging.Handler):
"""
A handler class which sends log strings to a wx object
"""
def __init__(self, wxDest=None):
"""
Initialize the handler
@param wxDest: the destination object to post the event to
@type wxDest: wx.Window
"""
logging.Handler.__init__(self)
self.wxDest = wxDest
self.level = logging.DEBUG
def flush(self):
"""
does nothing for this handler
"""
def emit(self, record):
"""
Emit a record.
"""
try:
msg = self.format(record)
evt = wxLogEvent(message=msg,levelname=record.levelname)
wx.PostEvent(self.wxDest,evt)
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
然後
self.Bind(EVT_WX_LOG_EVENT, self.onLogEvent)
def onLogEvent(self,event):
'''
Add event.message to text window
'''
msg = event.message.strip("\r")+"\n"
self.logwindow.AppendText(msg) # or whatevery
event.Skip()
您將需要創建自定義logging.Handler
並將其添加到您的logging.Logger
。
從文檔:
Handler
對象負責 調度相應的日誌 消息(基於日誌消息 嚴重性)的處理程序的規定 目的地。記錄器對象可以使用addHandler() 方法將 零個或多個處理程序對象本身添加到 本身。舉例來說, 應用程序可能希望將所有日誌 消息發送到日誌文件,所有日誌文件中包含錯誤或更高的錯誤消息,標準輸出, 以及所有對電子郵件地址至關重要的消息。這種情況下需要三個獨立的處理程序,其中每個處理程序負責將特定嚴重性的消息發送到 特定位置。
請參閱http://docs.python.org/library/logging.html#handler-objects爲Handler
API。
特別是,您可以使用Handler.emit(record)
方法來指定輸出的目的地。據推測,你會執行這個調用TextCtrl.AppendText
。
這裏有一個簡單的工作示例:
import logging
import random
import sys
import wx
logger = logging.getLogger(__name__)
class WxTextCtrlHandler(logging.Handler):
def __init__(self, ctrl):
logging.Handler.__init__(self)
self.ctrl = ctrl
def emit(self, record):
s = self.format(record) + '\n'
wx.CallAfter(self.ctrl.WriteText, s)
LEVELS = [
logging.DEBUG,
logging.INFO,
logging.WARNING,
logging.ERROR,
logging.CRITICAL
]
class Frame(wx.Frame):
def __init__(self):
TITLE = "wxPython Logging To A Control"
wx.Frame.__init__(self, None, wx.ID_ANY, TITLE)
panel = wx.Panel(self, wx.ID_ANY)
log = wx.TextCtrl(panel, wx.ID_ANY, size=(300,100),
style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
btn = wx.Button(panel, wx.ID_ANY, 'Log something!')
self.Bind(wx.EVT_BUTTON, self.onButton, btn)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(log, 1, wx.ALL|wx.EXPAND, 5)
sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
panel.SetSizer(sizer)
handler = WxTextCtrlHandler(log)
logger.addHandler(handler)
FORMAT = "%(asctime)s %(levelname)s %(message)s"
handler.setFormatter(logging.Formatter(FORMAT))
logger.setLevel(logging.DEBUG)
def onButton(self, event):
logger.log(random.choice(LEVELS), "More? click again!")
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = Frame().Show()
app.MainLoop()
截圖:
更新:正如iondiode指出的,如果您的應用程序中有多個線程,通過這樣的處理程序進行所有日誌記錄,則此簡單腳本可能會有問題;理想情況下只有一個UI線程應該更新UI。根據他的回答,您可以使用建議的使用自定義事件記錄事件的方法。
是行logging.Handler .__ init __(self)是否正確?在__init__中傳遞自己是否正確? – piertoni 2016-01-19 07:16:28
- 1. Java日誌記錄 - 如何將輸出重定向到記錄器的自定義日誌文件?
- 2. 與自定義處理程序的GWT遠程日誌記錄
- 3. 添加自定義處理程序與Python日誌記錄
- 4. 如何將npgsql日誌輸出重定向到log4net記錄器?
- 5. 將自定義函數輸出添加到Python日誌記錄處理程序
- 6. Live555將調試日誌重定向到自定義應用程序日誌記錄
- 7. ZF2日誌記錄:將自定義信息添加到日誌記錄輸出
- 8. Python,日誌記錄:使用自定義處理程序與字典配置?
- 9. Python的記錄器。不記錄自定義日誌項
- 10. Sailsjs - 用Winston自定義日誌記錄
- 11. 如何將TensorFlow日誌記錄重定向到文件?
- 12. Python日誌記錄處理程序
- 13. 圖像重定向和日誌記錄
- 14. 使用公共日誌記錄通過應用程序重定向日誌log4j.xml
- 15. Python日誌記錄自定義處理程序和格式化程序沒有被記錄
- 16. 使用Python日誌記錄管理日誌記錄器
- 17. django添加自定義日誌記錄到芹菜日誌記錄
- 18. 重新定義日誌根記錄
- 19. 自定義日誌記錄信息
- 20. ICN自定義日誌記錄
- 21. AWS自定義日誌記錄
- 22. 自定義日誌記錄 - CakePHP(1.3)
- 23. log4net自定義日誌記錄
- 24. CakePHP 3自定義日誌記錄
- 25. CakePHP 2.x:自定義日誌記錄
- 26. 自定義Python日誌記錄方法
- 27. 自定義Fluent日誌記錄
- 28. Rails3自定義日誌記錄選項?
- 29. 如何配置IBM WAS SystemOut日誌記錄以自定義每個應用程序的日誌記錄?
- 30. django日誌記錄「沒有處理程序可以找到記錄器」
@Vinjay Sajip:如果事件在wx主循環之外被記錄,你的回答不是線程安全的。使用wx事件處理來自外部線程的數據更安全。 – iondiode 2010-05-12 23:49:07
毫無疑問,你是對的,但我的回答只是指出要使用的方法,而不是提供經過戰場考驗的完整解決方案。 – 2010-05-13 14:42:26