Python uygulamasında, günlüğe kaydetme modülünü kullanarak çok sayıda ileti yazan bir modül kullanıyorum. Başlangıçta bunu bir konsol uygulamasında kullanıyordum ve konsol işleyicisi kullanarak konsolda görüntülemek için günlüğe kaydetme çıktısını almak oldukça kolaydı. Şimdi wxPython kullanarak uygulamasının bir GUI sürümünü geliştirdim ve tüm kayıt çıktısını özel bir denetime - çok satırlı bir textCtrl - görüntülemek istiyorum. Özel bir günlüğe kaydetme işleyicisi oluşturabilmemin bir yolu var, böylece tüm günlüğe kaydetme çıktısını orada yeniden yönlendirebilirim ve/veya istediğim yerde günlüğe kaydetme mesajlarını görüntüleyebilirim - bu durumda bir wxPython uygulaması.Kaydediciyi özel bir günlüğe kaydetme işleyicisi kullanarak bir wxPython textCtrl dosyasına nasıl yeniden yönlendirebilirim?
cevap
kontrolünüz Sonra
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)
işleyicisi oluştur
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()
Özel bir logging.Handler
oluşturmanız ve logging.Logger
ürününüze eklemeniz gerekecek. belgelerine
:
Handler
nesneler işleyicisi'nın belirtilen hedefe (günlük mesajlarının şiddetine göre) uygun günlük mesajlar gönderilmesi sorumludur. Logger nesneleri, bir addHandler() yöntemiyle sıfır veya daha fazla işleyici nesnesini yöntemine ekleyebilir. Örnek bir senaryo olarak, bir uygulaması, tüm günlük uygulamalarının bir günlük dosyasına, tüm günlük hata iletilerine veya daha yüksek iletilere, ve tüm önemli iletileri bir e-posta adresine göndermek isteyebilir. Bu senaryoda, her bir işleyicisinin işleyicisinin, belirli bir önem derecesine sahip iletilerinin belirli bir konuma belirli bir konuma gönderilmesinden sorumlu olduğu üç ayrı işleyici gerekir.
Handler
API için http://docs.python.org/library/logging.html#handler-objects'a bakın.
Özellikle, çıktı hedefini belirlemek için uygulayabileceğiniz Handler.emit(record)
yöntemidir. Muhtemelen, bunu TextCtrl.AppendText
'u aramak için uygularsınız.
Burada basit çalışma örnek:
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()
Ekran Görüntüsü:
Güncelleme: iondiode işaret ettiği gibi uygulamanızda birden evre varsa, bu basit script tüm böyle bir işleyici yoluyla oturum, sorunlar olabilir; İdeal olarak sadece bir UI iş parçacığı UI'yi güncellemelidir. Etkinliğin günlüğe kaydedilmesi için önerilen yaklaşımı, yanıtına göre özel bir etkinlik kullanarak kullanabilirsiniz.
, satır günlüğü oluyor.Handler .__ init __ (self) doğru mu?__init__ içinde kendini geçmek doğru mu? – piertoni
@Vinjay Sajip: Wx ana döngüsünün dışında olaylar kaydedilmişse cevabınız iş parçacığı güvenli değildir. Dış iş parçacıklarından veri işlemek için wx olaylarını kullanmak daha güvenlidir. – iondiode
Şüphesiz haklısınız, ama cevabım, sadece savaşta test edilmiş bir çözüm sunmaktan ziyade kullanılacak yaklaşımı işaret ediyor. –