2017-03-15 26 views
0

私はPyQt4に基づいてPython 2.7アプリケーションを持っています。特定のハンドラでCtrl + C(KeyboardInterruptSIGINT、2)を処理する必要があります。 Ctrl + Cを打つことによって作成された例外がtry-exceptブロックに捕捉されず、signalライブラリによって登録されたハンドラ関数には見られませんでした。 Ctrl + Cは何もしません!
私はPyQtなしで同じことをしようとしました - signalがうまくいきます。
テストに使用されるコードはPyQt APIを使用しないため、どちらの場合でも確認できました。PyQtを使用したPythonアプリケーションでCtrl + Cを処理する方法は?

答えて

1

CTRL + Cは、プロセスに信号を送信します。 Pythonはシグナルをキャッチし、CTRL_C_PRESSED = Trueのようなグローバル変数を設定します。次に、Pythonインタプリタが新しいオペコードを実行するたびに、変数セットを確認し、KeybordInterruptを発生させます。

これは、CTRL + Cが動作するのは、Pythonインタプリタが回転している場合のみです。インタプリタが長時間実行する操作を実行するC言語で書かれた拡張モジュールを実行している場合、CTRL + CはPythonと明示的に "協力"しない限り、中断しません。例:time.sleep()は理論的にはブロック操作ですが、その関数の実装はPythonインタプリタと連携してCTRL + Cを動作させます。

これはすべて仕様によるものです.CTRL + Cは、「クリーンアボート」を行うためのものです。これがPythonによって例外になって(クリーンアップがスタックアンワインド中に実行されるように)、拡張モジュールによるサポートは「オプトイン」のようなものです。クリーンアップする機会を与えずに、プロセスを完全に中止したい場合は、CTRL +を使用できます。

PythonがQApplication :: exec()(C++関数)を呼び出すとき、QtはPythonとCTRL + Cをどのように "協力"するかを知らないため、動作しません。私は「それを働かせる」良い方法があるとは思わない。グローバルイベントフィルタで処理できるかどうかを確認したい場合があります。 - Giovanni Bajo

これをメインプログラムに追加すると問題が解決しました。

import signal 

signal.signal(signal.SIGINT, signal.SIG_DFL) 

これは説明と関係がありません。

+0

これで、処理せずにプログラムを終了することができます。 Ctrl + Cを操作することは可能ですか? – Jury

+0

'インポートsignal' 'インポートsys' ' DEF signal_term_handler(信号、フレーム):' SIGTERM'' 'sys.exit(0) ' ' signal.signal(signal.SIGTERMを得」 '印刷、 signal_term_handler) ' –

関連する問題