本文介绍了捕获QApplication中引发的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to write an app that works in system tray using PyQt5.The code is sometimes raising exceptions, and I need to be able to catch them.

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

I would expect that when an exception occurs in an app, the main event loop is exited, so catching it like that should work:

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

例如,当我按下提高按钮时,我只看到回溯,但从未看到捕获到的错误!

In the following example, when I press the "Raise" button, I only see the traceback, but I never see the error catched! printed.

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!")

有两个类似的问题,但是答案那里没有做我需要做的事:

There are 2 similar questions, but the answers there don't do what I need to do:

:OP希望监视异常,偶数循环没有退出
:装饰器的答案根本行不通;将 sys.exit(1)添加到 sys.excepthook 只会关闭整个程序,而无需打印捕获了错误!

Grab any exception in PyQt: the OP wants to monitor the exceptions, the even loop isn't exitedPreventing PyQt to silence exceptions occurring in slots: the decorator answer simply doesn't work; adding sys.exit(1) to sys.excepthook just closes the whole program, without printing error catched!

推荐答案

您必须使用该异常,如果希望事件循环然后必须调用 quit()(或 exit())方法。

You must use the exception and, if you want the event loop to end then you must call the quit()(or exit()) method.

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

这篇关于捕获QApplication中引发的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-02 01:26