2009-01-03 91 views
1

我有一個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產生了一個不同的線程。

回答

1

我爲Chandler編寫了這樣的代碼,其中任何未處理的異常都會彈出一個包含堆棧和其他信息的窗口,並且用戶可以添加其他註釋(它們在發生什麼時發生等)並將其提交給Chandler開發人員。有點像Mozilla Talkbacknowadays他們使用Breakpad我相信)功能,如果你願意。

要在wxPython中執行此操作,您需要爲wx.App提供重定向參數。這會彈出wx.PyOnDemandOutputWindow(你可能想重寫它以提供更好看的實現)。

錢德勒相關的源文件所在的位置:

  • Chandler.py啓動應用程序,並設置重定向屬性,以及試圖趕上和的情況下,顯示錯誤對話框正常的應用程序啓動失敗
  • Application.py定製應用程序對象(包括設置我們的定製wx.PyOnDemandOutputWindow)將爲定製的wx.PyOnDemandOutputWindow;實現自定義wx.PyOnDemandOutputWindow;其中包含自定義wx.PyOnDemandOutputWindow;它還需要feedback.xrc和feedback_xrc.py
2

不知道這是否適用於wxPython應用程序,但是在sys模塊中,您可以覆蓋excepthook屬性,該屬性是一個函數,該函數使用3個參數(type, value, traceback)調用,當發生uncaugth異常時。你可以在那裏安裝你自己的函數,只處理你想要的異常,併爲所有其他函數調用原始函數。

諮詢:http://docs.python.org/library/sys.html#sys.excepthook

+0

我有一個wxPython應用程序非常類似的問題。我無法在_wx.App_中使用「redirect = True」(因爲在Chandler項目中),因爲我需要在控制檯窗口中使用_sys.stdout_。 _OnExceptionInMainLoop_似乎回到了wxPython 2.9,但它仍然是測試版,我不能要求客戶端安裝它。重寫「sys.excepthook」彈出一個自定義對話框,自定義日誌記錄對我來說工作得很好。 – bitman 2012-08-23 07:42:17

0

也許this問題可能是一些使用的,它試圖捕獲所有異常。

+1

請注意,該示例正在將app.MainLoop()封裝在try/except中。這不起作用,至少在我的任何嘗試中都沒有。 – Soviut 2009-01-03 19:06:30

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()