捕获QApplication中引发的异常

时间:2019-04-23 20:57:24

标签: python exception pyqt5

我正在尝试使用PyQt5编写可在系统任务栏中运行的应用程序。 该代码有时会引发异常,我需要能够捕获它们。

我希望当应用程序中发生异常时,主事件循环会退出,因此像这样捕获它应该起作用:

try:
    application.exec()
except:
    do_stuff()

在下面的示例中,当我按下“提高”按钮时,我仅看到回溯,但从未看到打印的error catched!

from PyQt5 import QtWidgets, QtGui, QtCore

class ErrorApp():
    def __init__(self):
        # Init QApplication, QWidet and QMenu
        self.app = QtWidgets.QApplication([])
        self.widget = QtWidgets.QWidget()
        self.menu = QtWidgets.QMenu("menu", self.widget)

        # Add items to menu
        self.menu_action_raise = self.menu.addAction("Raise")
        self.menu_action_raise.triggered.connect(self.raise_error)

        self.menu_action_exit = self.menu.addAction("Exit")
        self.menu_action_exit.triggered.connect(self.app.exit)

        # Create the tray app
        self.tray = QtWidgets.QSystemTrayIcon(QtGui.QIcon("logo.png"), self.widget)
        self.tray.setContextMenu(self.menu)

        # Show app
        self.tray.show()

    def raise_error(self):
        assert False

e = ErrorApp()

try:
    e.app.exec()

except:
    print("error catched!")

有2个类似的问题,但是那里的答案并没有满足我的要求:

Grab any exception in PyQt:OP希望监视异常,并且不退出偶数循环 Preventing PyQt to silence exceptions occurring in slots:修饰器答案根本行不通;将sys.exit(1)添加到sys.excepthook只会关闭整个程序,而无需打印error catched!

1 个答案:

答案 0 :(得分:2)

必须使用该异常,并且,如果要结束事件循环,则必须调用quit()(或exit())方法。

import sys
import traceback
from PyQt5 import QtWidgets, QtGui, QtCore


class ErrorApp:
    # ...

    def raise_error(self):
        assert False


def excepthook(exc_type, exc_value, exc_tb):
    tb = "".join(traceback.format_exception(exc_type, exc_value, exc_tb))
    print("error catched!:")
    print("error message:\n", tb)
    QtWidgets.QApplication.quit()
    # or QtWidgets.QApplication.exit(0)


sys.excepthook = excepthook
e = ErrorApp()
ret = e.app.exec_()
print("event loop exited")
sys.exit(ret)

输出:

error catched!:
error message:
 Traceback (most recent call last):
  File "main.py", line 28, in raise_error
    assert False
AssertionError

event loop exited