私の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と継承の違いは何ですか?
これはおそらく、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