0

ALL,

I'm trying to redirect python logging to the wxPython GUI. Here is my code:

class Redirect(object):
    def __init__(self, textctrl):
        self.out = textctrl

    def write(self, string):
        evt = UpdateLogCommandEvent(status=msg, peer=self)
        wx.PostEvent(self.out.GetEventHandler(), evt)

class LoggingRedirectHandler(logging.StreamHandler):
    def __init__(self,dialog):
        logging.StreamHandler.__init__( self )
        self.textctrl = dialog

    def emit(self, record):
        msg = self.format( record )
        stream = self.stream
        evt = UpdateLogCommandEvent(status=msg, peer=self)
        wx.PostEvent(self.textctrl.GetEventHandler(), evt)

class Executor(wx.Dialog):
    def __init__(self, parent, ID, title, options, path_spec):
        self.options = options
        self.path_spec = path_spec
        wx.Dialog.__init__( self, parent, ID, title, size=(600,600) )
        sizer1 = wx.BoxSizer( wx.VERTICAL )
        self.log = wx.TextCtrl( self, size=(800,800), style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL )
        sizer1.Add( self.log, 1, wx.EXPAND, 0 )
        self.SetSizer( sizer1 )
        sizer1.Fit( self )
        self.Bind(EVT_UPDATE_LOG_COMMAND_EVENT, self.OnUpdateLog)

    def OnUpdateLog(self, event):
        message = event.status
        peer = event.peer
        wx.CallAfter(self.log.WriteText, message + "\n" )
        #wx.Yield()

    def OnShowExecutor(self, logLevel):
        format_str = "[%(levelname)s] %(message)s"
        logging.basicConfig( level=logLevel, format=format_str )
        self.logger = logging.getLogger()
        self.logger.setLevel(logLevel)
        redir = Redirect(self)
        sys.stdout = redir
        sys.stderr = redir
        logger_stream_handler = LoggingRedirectHandler(self)
        self.logger.addHandler( logger_stream_handler )
        self.Show()
        logging.info("Logging check")

The problem I'm having is that the logging comes from another process' threads. So when I send the log messages in my newly created logger the application becomes unresponsive.

The process and threads are executing and the logging messages are coming to the console though, so that I can tell that the application works.

Now before the code was using wx.ProgressDialog() and there was no GUI freeze. My guess is that progress dialog rans on its own thread and it is called wx.Yield() to make sure that the GUI is updated.

Now I tried to call wx.Yield() in my code as well so that let the GUI process the messages/events it has in the queue, but with the same result - the GUI freezes.

What am I missing here? How do I unfreeze my GUI part?

Thank you.

P.S.: I'm using wxPython-3.0.0 classic with python-2.7 on WinXP SP3. But the same happens on the newer WIndows 7/8 machines with the same python/wxPython versions.

P.P.S. [EDIT] I apologize for the code formatting. For some reason SO screwwed the code formatting and it does not keep the spaces. Sorry about that. [/EDIT]

Igor
  • 5,620
  • 11
  • 51
  • 103
  • Are you trying to get log message to textctrl? If so, will this work for you? http://stackoverflow.com/q/2819791/566035 or, my favorite trick is http://www.blog.pythonlibrary.org/2009/01/01/wxpython-redirecting-stdout-stderr/ – otterb Jun 16 '14 at 14:57
  • @otterb, did you see the code I posted? Yes I'm trying to redirect the log from another process' thread to the wx.Dialog's text control. And I wrote it just like in the first link and it still freezes the GUI. – Igor Jun 17 '14 at 02:22

0 Answers0