MainLoop 例外をキャッチし、メッセージダイアログに表示する
-
03-07-2019 - |
質問
外部構成ファイルに依存する wxPython アプリケーションがあります。構成エラーがある場合に表示されるわかりやすいメッセージ ダイアログを提供したいと考えています。app.MainLoop() 呼び出しを try/Except ステートメントでラップすることで、これを機能させようとしました。
以下のコードは、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 メソッドについての記述を読んだことがありますが、wx.App にはその名前のメソッドがないようなので、私が読んだソースは古い (2004 年) はずです。
編集:
メインループ中に未処理の例外をキャッチして、それらをさらに処理してエラー ダイアログに表示し、サイレントで通過したり、アプリを終了したりしないようにする必要があります。
sys.Excepthook ソリューションは低レベルすぎるため、wxPython メインループ スレッドとうまく連携しません。他の回答へのリンクは、メインループのラップを除いて同じ試みを行いますが、これもまた、wxPythonがアプリ/UI用に別のスレッドを生成するため、機能しません。
解決
このようなものをコード化しました チャンドラー, ここで、未処理の例外があると、スタックやその他の情報を示すウィンドウがポップアップ表示され、ユーザーは追加のコメント (例外が発生したときに何をしたかなど) を入力して、Chandler 開発者に送信できます。少し似ています Mozilla トークバック (最近では 彼らは Breakpad 機能を使用していると思います)。
wxPython でこれを行うには、wx.App にリダイレクト パラメーターを提供する必要があります。これがポップアップします wx.PyOnDemandOutputWindow (おそらく、より見栄えの良い実装を提供するためにこれをオーバーライドする必要があるでしょう)。
Chandler の関連ソース ファイルは次のとおりです。
- チャンドラー.py アプリケーションを起動してリダイレクト属性を設定し、通常のアプリケーションの起動が失敗した場合に備えてエラー ダイアログをキャッチして表示しようとします。
- Application.py カスタマイズされた wx.PyOnDemandOutputWindow の設定を含む、アプリケーション オブジェクトをカスタマイズします。
- フィードバック.py カスタマイズされた wx.PyOnDemandOutputWindow の実装があります。さらに、feedback.xrc と Facebook_xrc.py が必要になります。
他のヒント
これが wxPython アプリケーションで機能するかどうかはわかりませんが、sys モジュールでは、3 つの引数で呼び出される関数である、Excepthook 属性を上書きできます。 (type, value, traceback)
, 、キャッチされなかった例外がキャッチされた場合。必要な例外のみを処理する独自の関数をそこにインストールし、他の例外については元の関数を呼び出すことができます。
相談する: http://docs.python.org/library/sys.html#sys.Excepthook
多分 これ この質問は何らかの役に立つかもしれません。すべての例外をキャプチャしようとします。
非常によく似た問題でうまくいった解決策を投稿します。
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()
使用する sys.excepthook
私にとってはとても良いことです。
次の記事が非常に役に立ちます。 wxPython:どこからでも例外をキャッチする.