Usually, if you call a non-existing method on a PyQt5 object, like calling .show()
on a boolean variable as in the click handler below, which is an example that will always trigger an exception:
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()
So when I click the button in this example, I get:
---------------------------
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
---------------------------
Ok - but if I wrap the app.exec()
in try ... catch
block, - obviously, - it does not catch this exception (probably because its from a C++ PyQt5 object)?
So, my question is: can I somehow catch/handle this kind of an exception in python (but hopefully somewhere "down the chain", as in trying to catch any such application exception with a single statement, as I've tried to do with try ... catch
around app.exec()
)?
Try it:
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())