qt 记录-处理 QThread
有一次遇到一个问题:
QObject::setParent: Cannot set parent, new parent is in a different thread
这个错误曾经让我 DEBUG 了半天。这个绝对是因为某个 GUI 里面用了一个 QThread,然后对这个 QThread 进行了什么处理。
我当时信誓旦旦觉得我没这样做。但最后发现:我是在 GUI 里面设置了一个 QThread,我在 main.py
中有一个全局异常处理函数,每次异常后就进入这个函数了。
def show_error_dialog_in_main_thread():
msg_box = QMessageBox()
msg_box.setWindowFlags(msg_box.windowFlags() | Qt.WindowStaysOnTopHint)
msg_box.setIcon(QMessageBox.Critical)
msg_box.setWindowTitle("未处理的错误")
msg_box.setText(f'发生错误,请检查 {os.path.dirname(__file__)} 中的 LOG.txt 文件')
msg_box.exec_()
# 错误框关闭后退出
sys.exit(1)
def global_exception_handler(exctype, value, tb):
print(f'{time.strftime("%Y-%m-%d %H:%M:%S")}\n')
traceback.print_exception(exctype, value, tb, file=sys.stdout)
# 出错时,会新建一个 QMessageBox
show_error_dialog_in_main_thread()
但是如果是 QThread 里面报错,同样会到这个函数,此时进入到这个函数是在 QThread 这个线程了,此时新建 GUI 就会有问题。
处理方式就是需要 GUI 中连接 QThread 的错误信号,即让它回到主线程上来。
class CpatureWin(QWidget, window_2.Ui_Form):
def __init__(self):
# ...
self.capture_thread = captureThread.CaptureThread()
# ! 连接错误信号,不这样做全局捕获异常会有问题
self.capture_thread.error_occurred.connect(self.handle_thread_error)
# QThread 出错时,直接向上报错
def handle_thread_error(self, error_msg):
raise Exception(error_msg)