4

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

下面的代码适用于我的 MainWindow 框架类中的初始化代码,但不会捕获 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 似乎不再具有该名称的方法。

编辑:

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

sys.excepthook 解决方案级别太低,与 wxPython 主循环线程不兼容。虽然指向另一个答案的链接执行相同的尝试/除了环绕主循环,但由于 wxPython 再次为应用程序 / ui 生成不同的线程而无法正常工作。

4

5 回答 5

2

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

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

于 2009-01-03T16:04:33.753 回答
1

我为Chandler编写了类似的代码,其中任何未处理的异常都会弹出一个包含堆栈和其他信息的窗口,用户可以添加额外的评论(当它发生时他们做了什么等)并将其提交给 Chandler 开发人员。如果你愿意的话,有点像Mozilla Talkback(我相信现在他们使用 Breakpad)功能。

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

Chandler 中的相关源文件在这里:

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

也许这个问题可能有一些用处,它试图捕获所有异常。

于 2009-01-03T18:24:54.767 回答
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()
于 2012-08-24T12:44:48.130 回答
0

使用sys.excepthook对我来说非常好。

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

于 2018-10-25T12:50:41.710 回答