如何在wxPython中制作类似日志框的组件

5 投票
2 回答
5573 浏览
提问于 2025-04-16 14:46

我想这应该可以通过一个多行文本框来实现,但我不太确定怎么做。我想在我的wxPython程序里做一个日志框,当某些操作发生时,我可以在里面写消息。此外,我还需要在代码的某些时刻写消息,而不仅仅是在事件发生时。我该怎么让窗口重新绘制,这样消息就能立刻显示出来呢?

2 个回答

4

如果你想在wxpython中显示一个日志对话框,可以使用wx.LogWindow:

import wx

class MainWindow(wx.Frame):

    def __init__(self, parent=None):
        wx.Frame.__init__(self, parent, wx.NewId(), 'Logging')

        self.log_window = wx.LogWindow(self, 'Log Window', bShow=True)

        box_sizer = wx.BoxSizer(orient=wx.VERTICAL)        
        show_log_button = wx.Button(self, wx.NewId(), 'Show Log')
        show_log_button.Bind(wx.EVT_BUTTON, self._show_log)        

        log_message_button = wx.Button(self, wx.NewId(), 'Log Message')
        log_message_button.Bind(wx.EVT_BUTTON, self._log_message)

        box_sizer.AddMany((show_log_button, log_message_button))
        self.SetSizer(box_sizer)
        self.Fit()

        self.Bind(wx.EVT_CLOSE, self._on_close)

    def _show_log(self, event):
        self.log_window.Show()

    def _log_message(self, event):
        wx.LogError('New error message')

    def _on_close(self, event):
        self.log_window.this.disown()
        wx.Log.SetActiveTarget(None)
        event.Skip()

if __name__ == '__main__':
    app = wx.PySimpleApp()
    dlg = MainWindow()
    dlg.Show()
    app.MainLoop()

这里的bShow是指这个对话框一开始是否显示。使用这个功能可以很好地记录你所有的wx.LogX消息,这些消息可以被你触发,而且它还会把这些消息传递给其他处理程序。

另外一种方法是用Python记录日志,然后在打开一个带有文本框的窗口时,使用LoadFile来打开日志文件:

import logging
LOG_FILENAME = 'example.log'
logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)

logging.debug('This message should go to the log file')

然后,当你在某个地方创建一个wx.TextCtrl时:

log_control = wx.TextCtrl(self, wx.NewId(), style=wx.TE_MULTILINE|wx.TE_READONLY)
log_control.LoadFile('example.log')

编辑:现在这个功能可以和_on_close事件一起使用了!感谢Fenikso

6

我几年前写过一篇关于这个主题的文章:

http://www.blog.pythonlibrary.org/2009/01/01/wxpython-redirecting-stdout-stderr/

撰写回答