QThread重写run方法添加return super().run()后不触发finished信号原因咨询
QThread调用super().run()后不发finished信号的原因
问题本质
PyQt的QThread和Python标准库threading.Thread的run()方法底层逻辑完全不同:
- 对于
threading.Thread,它的run()默认要么执行你传入的target函数,要么啥也不干。所以你在自定义run()里调用super().run(),只是执行了一个空实现,线程跑完自己的逻辑就正常结束,不会有阻塞。 - 但PyQt的QThread默认的
run()方法会启动一个Qt事件循环(exec()),这个循环会一直运行,直到你主动调用quit()或exit()去终止它。当你在自定义run()末尾加上return super().run()时,线程执行完自己的打印逻辑后,就进入了这个永不停止的事件循环,线程永远不会结束,自然不会发出finished信号。
解决方法
- 如果你不需要在这个线程里运行Qt事件循环,直接删掉
return super().run(),让run()执行完自定义逻辑后自然结束,线程就会正常触发finished信号。 - 如果确实需要事件循环,那你要在合适的时机调用
self.quit()来终止循环,比如在run()的自定义逻辑完成后添加:def run(self) -> None: print('created QThread Example') self.quit() # 终止事件循环 return super().run()
代码对比
threading.Thread测试代码
#!/usr/bin/env python3 import threading class InThreading(threading.Thread): def __init__(self): super(InThreading, self).__init__() def run(self) -> None: print('threading thread') print(threading.enumerate()) return super().run() if __name__ == '__main__': inthreadng = InThreading() print(threading.enumerate()) inthreadng.start() inthreadng.join() print(threading.enumerate())
QThread测试代码(修改前)
#!/usr/bin/env python3 import sys from PyQt5.QtCore import QThread from PyQt5.QtWidgets import QApplication, QMainWindow class User_Interface(QMainWindow): def __init__(self): super(User_Interface, self).__init__() self.usage() def usage(self): qtthread = QtThread(self) qtthread.start() qtthread.finished.connect(lambda: print('qtthrediing finished!')) class QtThread(QThread): def __init__(self, parent): super(QtThread, self).__init__(parent=parent) def run(self) -> None: print('created QThread Example') return super().run() if __name__ == '__main__': app = QApplication(sys.argv) ui = User_Interface() ui.show() sys.exit(app.exec_())
内容的提问来源于stack exchange,提问作者ssayno
相关产品推荐
相关产品推荐

