web-dev-qa-db-ja.com

PyQt:終了時にエラーメッセージ(トレースバック)はありません

私のPyQtアプリケーションは、エラー(stderr?)をコンソールに出力しなくなりました。

QtDesignerを使用して、次のようにUIをインポートします。

from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from PyQt5.uic import loadUiType
Ui_MainWindow, QMainWindow = loadUiType("test.ui")

class Main(QMainWindow, Ui_MainWindow):
    """Main window"""
    def __init__(self,parent=None):
        super(Main, self).__init__(parent)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.testfunc)

   def testfunc(self):
        print(9/0)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    main = Main()
    main.show()
    sys.exit(app.exec_())

test.uiには、QPushButtonとラベルが含まれています。 Qt以外のアプリケーションでtestfunc(明らかにエラーが発生します)を呼び出すと、エラーメッセージ、トレースバックなどが表示されます。このコードを実行すると、終了するだけです。

以前にQtDesignerを使用せずにPyQtアプリケーションを作成しましたが、期待どおりにエラーがコンソールに出力されました。 QtDesignerと継承の違いは何ですか?

15
Jannis

これはおそらく、PyQt-5.5での例外の処理方法の変更によるものです。 PyQt5 Docs から引用するには:

PyQt v5.5では、未処理のPython例外により、QtのqFatal()関数が呼び出されます。デフォルトでは、これによりabort()が呼び出され、アプリケーションが終了します。アプリケーションが例外をインストールしたことに注意してください。フックは引き続き優先されます。

通常のコンソールで例を実行すると、次のように表示されます。

$ python test.py
Traceback (most recent call last):
  File "test.py", line 213, in testfunc
    print(9/0)
ZeroDivisionError: division by zero
Aborted (core dumped)

したがって、主な違いは、未処理の例外が発生するとアプリケーションがすぐに中止されることです(つまり、通常のpythonスクリプトのように)。もちろん、try/exceptを使用してこの動作を制御できます。 sys.excepthook をオーバーライドしてブロックまたはグローバルに。

トレースバックが表示されない場合は、アプリケーションの実行に使用しているPython IDE)の問題が原因である可能性があります。

PS:

最低限、トレースバックをstdout/stderrに出力するだけの古いPyQt4の動作は次のように復元できます。

def except_hook(cls, exception, traceback):
    sys.__excepthook__(cls, exception, traceback)

if __name__ == "__main__":

    import sys
    sys.excepthook = except_hook
28
ekhumoro