Перехват исключений, возникающих в QApplication - PullRequest
1 голос
/ 23 апреля 2019

Я пытаюсь написать приложение, которое работает в системном трее, используя 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 похожих вопроса, но ответы на них не делают то, что мне нужно сделать:

Получите любое исключение в PyQt : OP хочет отслеживать исключения, четный цикл не завершен Запрет PyQt для подавления исключений, возникающих в слотах : ответ декоратора просто не работает; добавление sys.exit(1) к sys.excepthook просто закрывает всю программу без печати error catched!

1 Ответ

2 голосов
/ 24 апреля 2019

Вы должны использовать исключение, и, если вы хотите, чтобы цикл событий завершился, вы должны вызвать метод 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...