捕获MainLoop异常并在MessageDialogs中显示它们
我有一个wxPython应用程序依赖于外部配置文件。我想提供友好的消息对话框,显示是否有任何配置错误。我试图通过在try/except语句中包装我的app.MainLoop()调用来完成这项工作。捕获MainLoop异常并在MessageDialogs中显示它们
下面的代码适用于我的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似乎不再有这个名字的方法。
编辑:
我需要能够赶上未处理的异常,我的主循环中,这样我可以进一步处理他们,在错误对话框显示出来,而不是默默传递,而不是终止应用程序。
sys.excepthook解决方案太低级别,并与wxPython主循环线程打不开。虽然到另一个答案的链接做了相同的尝试/除了包装在主循环中不能正常工作,wxPython再次为app/ui产生了一个不同的线程。
我为Chandler编写了这样的代码,其中任何未处理的异常都会弹出一个包含堆栈和其他信息的窗口,并且用户可以添加其他注释(它们在发生什么时发生等)并将其提交给Chandler开发人员。有点像Mozilla Talkback(nowadays他们使用Breakpad我相信)功能,如果你愿意。
要在wxPython中执行此操作,您需要为wx.App提供重定向参数。这会弹出wx.PyOnDemandOutputWindow(你可能想重写它以提供更好看的实现)。
钱德勒相关的源文件所在的位置:
- Chandler.py启动应用程序,并设置重定向属性,以及试图赶上和的情况下,显示错误对话框正常的应用程序启动失败
- Application.py定制应用程序对象(包括设置我们的定制wx.PyOnDemandOutputWindow)将为定制的wx.PyOnDemandOutputWindow;实现自定义wx.PyOnDemandOutputWindow;其中包含自定义wx.PyOnDemandOutputWindow;它还需要feedback.xrc和feedback_xrc.py
不知道这是否适用于wxPython应用程序,但是在sys模块中,您可以覆盖excepthook属性,该属性是一个函数,该函数使用3个参数(type, value, traceback)
调用,当发生uncaugth异常时。你可以在那里安装你自己的函数,只处理你想要的异常,并为所有其他函数调用原始函数。
发布解决方案,为我工作的一个非常类似的问题。
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()
我有一个wxPython应用程序非常类似的问题。我无法在_wx.App_中使用“redirect = True”(因为在Chandler项目中),因为我需要在控制台窗口中使用_sys.stdout_。 _OnExceptionInMainLoop_似乎回到了wxPython 2.9,但它仍然是测试版,我不能要求客户端安装它。重写“sys.excepthook”弹出一个自定义对话框,自定义日志记录对我来说工作得很好。 – bitman 2012-08-23 07:42:17