从QThread发送信号导致程序崩溃的问题排查
问题原因及解决方案
你的代码崩溃核心原因是自定义信号的定义方式完全错误,具体问题和修正方法如下:
错误点分析
- 不能用
pyqtBoundSignal定义新信号:pyqtBoundSignal是信号绑定到槽函数后生成的对象类型,用来定义原始信号的应该是pyqtSignal。 - 自定义信号必须在QObject子类的类级别声明:信号不能在
__init__方法里作为实例属性定义,必须放在类定义的顶层,PyQt会在类初始化时处理信号的注册逻辑。 - 额外问题:把
MyThread定义在函数内部虽语法合法,但不利于代码维护和信号机制稳定,建议将线程类移到全局作用域。
修正后的代码
from PyQt6.QtCore import QThread, pyqtSignal from PyQt6.QtWidgets import QMainWindow # 将线程类移至全局作用域 class MyThread(QThread): # 类级别声明自定义信号 progress = pyqtSignal(int) def __init__(self, parent=None): super().__init__(parent) def run(self): try: for i in range(1000): self.progress.emit(i) except Exception as exc: print(f"线程异常: {exc}") class TheWindow(QMainWindow): # ... 其他业务代码 ... def on_menu_item(self): th = MyThread(self) th.progress.connect(lambda i: print(i)) th.start()
原理说明
PyQt的信号槽机制依赖QObject的元对象系统,只有在类级别用pyqtSignal声明的信号,才能被元对象系统正确识别和管理。直接用pyqtBoundSignal实例化信号会绕过该机制,导致内存访问错误或信号发射时的内部崩溃,且这类错误通常不会抛出Python层面的异常,直接引发程序崩溃。
内容的提问来源于stack exchange,提问作者Seva Alekseyev
相关产品推荐
相关产品推荐

