いくつかのウィジェットとボタンを表示している PyQt プログラムがあります。
プログラムをスタンドアロンの python インスタンスとして、または ipython 環境内で実行したいと考えています。この場合、Jupyter コンソールで次のマジック コマンドを使用します (以前は、ipython qtconsole を起動するときに --gui=qt を使用する必要がありました)。
%pylab qt
両方の方法で動作するプログラムを作成するために、私のメイン モジュールには次の行があります。
APP = QtGui.Qapplication.instance() # retrieves the ipython qt application if any
if APP is None:
APP = QtGui.QApplication(["foo"]) # create one if standalone execution
if __name__=='__main__':
APP.exec_() # Launch the event loop here in standalone mode
ここに私の問題があります。イベント ループによって生成された例外は、バックグラウンド コンソールでポップアウトされるため、ユーザーが検出するのが非常に困難です。イベント ループで発生した例外をキャッチし、警告を表示したいと考えています (たとえば、QMainWindow ステータス バーに例外が発生したことをユーザーに知らせるため)。
私はいくつかの戦略を試しましたが、これを不可能にするために PyQt と Ipython の内部機構の間に陰謀があるようです:
- sys.excepthook の再実装 (スロットで発生する例外を黙らせる PyQt の防止を参照): ipython が sys.excepthook を上書きし続けるため、機能しない
- IPython が実行されているかどうかを検出し、IPYTHON.set_custom_exc を使用する ((キャッチされていない) 例外で IPython シェルを開く): 残念ながら、qt イベント ループの例外はハンドラーをトリガーしません。
- QApplication.notify の上書き: 残念ながら、派生関数で呼び出す予定のネイティブ QApplication.notify 関数は例外をスローしておらず、戻り値 (ブール値) もスロットの正しい実行を反映していません。このスレッドの答えは興味深いです: QApplication のキャッチされていない例外をログに記録する方法は? ただし、この戦略は Qt c++ で機能するようですが、notify の python ラッパーは、例外を発生させるのではなく、コンソールに出力するだけです。
昔からずっと頭を悩ませている問題です。誰にも解決策がありますか?