"""
Author: HECE - University of Liege, Pierre Archambeau
Date: 2024
Copyright (c) 2024 University of Liege. All rights reserved.
This script and its content are protected by copyright law. Unauthorized
copying or distribution of this file, via any medium, is strictly prohibited.
"""
"""
Logging handler to redirect messages sent to the python logging module to wx if necessary
How tu use it :
import logging
from wolfhece.pylogging import create_wxlogwindow
myapp = wx.App()
create_wxlogwindow('My first wx log Window')
and use logging as usual
"""
import wx
import logging
[docs]
class LoggingPythonWxBridgeHandler(logging.Handler):
def __init__(self, winTitle: str = "Log", show=True):
# assert wxParent is not None, "You must provide an initial parent frame"
super().__init__()
# This is a member variable so that the GC
# doesn't kill the window too early.
# When the WxApp closes, it will close this window
# and that may invalidate the variable. So
# use the variable with care.
self._log_window = wx.LogWindow(None, winTitle)
self._log_window.PassMessages(False) # évite que les messages ne soit affichés en popup en plus de la fenêtre de Logs
[docs]
def emit(self, record: logging.LogRecord):
if record.levelno < logging.DEBUG:
wx.LogVerbose(record.getMessage())
elif record.levelno < logging.INFO:
wx.LogDebug(record.getMessage())
elif record.levelno < logging.WARNING:
wx.LogMessage(record.getMessage())
elif record.levelno < logging.ERROR:
wx.LogWarning(record.getMessage())
else:
wx.LogError(record.getMessage())
[docs]
def create_wxlogwindow(winTitle='Log') -> wx.LogWindow:
log_bridge_handler=None
if wx.App.Get() is not None:
"""
test if a LoggingPythonWxBridgeHandler exists
if it is the case, nothing to do
otherwise, create it !
"""
create=True
for curhand in logging.getLogger().handlers:
if isinstance(curhand, LoggingPythonWxBridgeHandler):
create=False
if create:
log_bridge_handler = LoggingPythonWxBridgeHandler(winTitle)
logging.getLogger().addHandler(log_bridge_handler)
# Set some logging level, just to show up.
logging.getLogger().setLevel(logging.INFO)
log_bridge_handler.setLevel(logging.INFO)
wx.Log.SetVerbose(True)
return log_bridge_handler._log_window
return None
[docs]
class ADemonstrationFrame(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)
self.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(self.log, 1, wx.ALL|wx.EXPAND, 5)
sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
panel.SetSizer(sizer)
if __name__ == "__main__":
import sys
frame = ADemonstrationFrame()
# Connect the python logging to the wx one.
log_bridge_handler = LoggingPythonWxBridgeHandler()
logging.getLogger().addHandler(log_bridge_handler)
# Set some logging level, just to show up.
logging.getLogger().setLevel(logging.DEBUG)
log_bridge_handler.setLevel(logging.INFO)
# Make sure debug-lvl messages show up in the log window eventhough
# we discard the debug level later on
wx.Log.SetVerbose(True)
# Just for fun, add a "log to console" too...
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter( logging.Formatter('[%(levelname)s] %(asctime)s: %(message)s'))
console_handler.setLevel(logging.DEBUG)
logging.getLogger().addHandler(console_handler)
frame.Show()
app.MainLoop()