捕获MainLoop异常并在MessageDialogs中显示它们

时间:2009-01-03 09:22:51

标签: python exception-handling wxpython wxwidgets

我有一个依赖外部配置文件的wxPython应用程序。我想提供友好的消息对话框,以显示是否有任何配置错误。我试图通过在try / except语句中包装我的app.MainLoop()调用来完成这项工作。

下面的代码适用于我的MainWindow框架类中的init代码,但不捕获MainLoop中发生的任何异常。我怎样才能抓住这些例外?

if __name__ == '__main__':
    app = MyApp(0)
    try:
        MainWindow(None, -1, 'My Cool App')
        app.MainLoop()
    except ConfigParser.Error, error_message:
        messagebox = wx.MessageDialog(None, error_message, 'Configuration Error', wx.OK | wx.ICON_ERROR)
        messagebox.ShowModal()

我已经读过一些可以在wx.App类中重写的OnExceptionInMainLoop方法,但是我读的源必须是过时的(2004),因为wx.App似乎不再有一个方法名。

修改

我需要能够在mainloop期间捕获未处理的异常,以便我可以进一步处理它们并在错误对话框中显示它们,而不是静默传递,而不是终止应用程序。

sys.excepthook解决方案的级别太低,并且与wxPython主循环线程不兼容。虽然到另一个答案的链接执行相同的尝试/除了环绕主循环,这是不能正常工作,再次,wxPython为app / ui产生不同的线程。

5 个答案:

答案 0 :(得分:2)

不知道这是否适用于wxPython应用程序,但是在sys模块中,您可以覆盖excepthook属性,该属性是一个带有3个参数(type, value, traceback)的函数,当捕获到unaugth异常时。您可以在那里安装自己的函数,只处理您想要的异常,并为所有其他函数调用原始函数。

咨询:http://docs.python.org/library/sys.html#sys.excepthook

答案 1 :(得分:1)

我为Chandler编写了类似的内容,其中任何未处理的异常会弹出一个带有堆栈和其他信息的窗口,用户可以添加其他注释(当它发生时它们做了什么等)并提交它适用于Chandler开发人员。有点像Mozilla Talkbacknowadays他们使用Breakpad我相信)功能,如果你愿意的话。

要在wxPython中执行此操作,您需要向wx.App提供重定向参数。这将弹出wx.PyOnDemandOutputWindow(您可能希望覆盖它以提供更好看的实现)。

钱德勒的相关源文件在这里:

  • Chandler.py启动应用程序并设置重定向属性,并尝试捕获并显示错误对话框以防正常应用程序启动失败
  • Application.py自定义应用程序对象,包括设置我们的自定义wx.PyOnDemandOutputWindow
  • feedback.py具有自定义wx.PyOnDemandOutputWindow的实现;它还需要feedback.xrc和feedback_xrc.py

答案 2 :(得分:0)

也许this问题可能有用,它会尝试捕获所有异常。

答案 3 :(得分:0)

发布适用于我的解决方案,但问题非常类似。

import wx
import sys
import traceback

class Frame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None)
        panel = wx.Panel(self)
        m_close = wx.Button(panel, -1, "Error")
        m_close.Bind(wx.EVT_BUTTON, self.OnErr)
    def OnErr(self, event):
        1/0

def handleGUIException(exc_type, exc_value, exc_traceback):
    err_msg = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback))
    err_msg += '\n Your App will now terminate'
    # Here collecting traceback and some log files to be sent for debugging.
    # But also possible to handle the error and continue working.
    dlg = wx.MessageDialog(None, err_msg, 'Termination dialog', wx.OK | wx.ICON_ERROR)
    dlg.ShowModal()
    dlg.Destroy()
    sys.exit()

sys.excepthook = handleGUIException

if __name__ == '__main__':
    app = wx.App(redirect=False) 
    top = Frame()
    top.Show()
    app.MainLoop()

答案 4 :(得分:0)

使用sys.excepthook对我来说很好。

我发现以下对您有很大帮助的文章: wxPython: Catching Exceptions from Anywhere