通常,如果您在 PyQt5 对象上调用不存在的方法,例如在布尔变量上调用
.show()
,如下面的单击处理程序所示,这是一个始终会触发异常的示例:
import sys, os
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
print("Hello from MainWindow")
self.setWindowTitle("My App")
button = QPushButton("Press me!")
button.clicked.connect(self.button_clicked)
self.setCentralWidget(button)
def button_clicked(self, s):
print("click", s)
s.show()
def main(argv=None):
app = QApplication(sys.argv)
window = MainWindow()
window.show()
try:
app.exec()
except:
print("Exception")
if __name__ == '__main__':
main()
因此,当我单击此示例中的按钮时,我得到:
---------------------------
My App: python3.exe - Fail Fast Exception
---------------------------
A fail fast exception occurred. Exception handlers will not be invoked and the process will be terminated immediately.
---------------------------
OK
---------------------------
好的 - 但如果我将
app.exec()
包装在 try ... catch
块中,- 显然,- 它不会捕获此异常(可能是因为它来自 C++ PyQt5 对象)?
所以,我的问题是:我能以某种方式捕获/处理Python中的这种异常吗(但希望在“链下”的某个地方,就像尝试用一条语句捕获任何此类应用程序异常一样,正如我尝试过的那样)与
try ... catch
周围的 app.exec()
相关)吗?
尝试一下:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, \
QPushButton, QMessageBox
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
print("\nHello from MainWindow")
self.setWindowTitle("My App")
button = QPushButton("Press me!")
button.clicked.connect(self.button_clicked)
self.setCentralWidget(button)
def button_clicked(self, checked):
print(f"\nbutton checked: {checked}\n")
checked.show()
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
import traceback
def except_hook(exc_type, exc_value, exc_tb):
tb = "".join(traceback.format_exception(exc_type, exc_value, exc_tb))
msg = QMessageBox.warning(
None,
'Attention! ERROR!',
f'{tb}'
)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if __name__ == '__main__':
app = QApplication(sys.argv)
sys.excepthook = except_hook # +++ <----
window = MainWindow()
window.show()
exit(app.exec())