Я не могу понять исключения в QThreads. Рассмотрим этот пример:
from PyQt5 import QtCore, QtGui, QtWidgets
import time
class Worker(QtCore.QObject):
@QtCore.pyqtSlot()
def do_stuff(self):
print("Hello from worker")
time.sleep(2)
raise Exception("worker crashed")
class Gui(QtWidgets.QWidget):
def __init__(self):
super(Gui, self).__init__()
self.worker = Worker()
self.thread = QtCore.QThread()
self.worker.moveToThread(self.thread)
self.thread.start()
button = QtWidgets.QPushButton(text="do stuff in worker")
button.clicked.connect(self.worker.do_stuff)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(button)
self.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = Gui()
app.exec_()
Gui создает объект Worker, перемещает его в QThread и запускает его. Рабочий объект может получать сигналы и обрабатывать их в собственном потоке, чтобы не блокировать Gui.
Однако, если внутри рабочего процесса возникает исключение, вся программа вылетает с (на windows) ошибкой STATUS_STACK_BUFFER_OVERRUN (0xC0000409). Кажется, что ожидаемое поведение с версии PyQt 5.5
В этой ситуации исправление, которое, как представляется, рекомендуется, - это перехватить исключения в работнике, возможно, послать сигнал обратно в Gui с некоторой информацией об исключении, и пусть это обработает. Это решение не кажется идеальным, так как для этого потребовалось бы обернуть каждый метод в worker с помощью некоторого механизма try / except.
Есть ли другое решение? Как правильно обрабатывать сбои в QThreads?