Python 为什么QDialog中发出的信号不能调用QThread中连接的插槽?
这是我的代码:Python 为什么QDialog中发出的信号不能调用QThread中连接的插槽?,python,pyside,Python,Pyside,这是我的代码: from PySide import QtCore, QtGui import sys import time class TestThread(QtCore.QThread): def __init__(self): self.finished_flag = False super(TestThread, self).__init__() def finished(self): print('========
from PySide import QtCore, QtGui
import sys
import time
class TestThread(QtCore.QThread):
def __init__(self):
self.finished_flag = False
super(TestThread, self).__init__()
def finished(self):
print('==========finished function is invoked!=======================')
self.finished_flag = True
def run(self):
while(True):
print('thread is running...')
time.sleep(1)
if self.finished_flag:
print('thread exist!')
break
class TestDialog(QtGui.QDialog):
ForceTermimateSignal = QtCore.Signal()
def done(self, code):
print('================dialog done!==================')
self.ForceTermimateSignal.emit()
super(TestDialog, self).done(code)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dlg = TestDialog()
testThread = TestThread()
dlg.ForceTermimateSignal.connect(testThread.finished)
testThread.start()
dlg.exec_()
if testThread.isFinished():
print('thread finished')
else:
print('thread is still running!')
testThread.wait()
这是运行上述代码然后关闭对话框时的结果:
thread is running...
thread is running...
thread is running...
thread is running...
================dialog done!==================
thread is still running!
thread is running...
thread is running...
thread is running...
所以我想知道:为什么dlg发出的ForceTermimateSignal不能调用object testThread的'finished'函数 将信号连接到同一线程中的插槽时,将直接同步调用该插槽。但是,当连接是跨线程的时,信号将作为事件发布,插槽将被异步调用 在您的示例中,这一行:
self.ForceTermimateSignal.emit()
将向对话框的事件队列添加一个信号事件,然后返回,而不直接调用线程的finished
插槽。以下一行:
super(TestDialog, self).done(code)
然后将立即执行,这将在有机会处理信号事件之前终止事件循环
如果将发射线替换为:
testThread.finished_flag = True
这个例子应该可以像预期的那样工作。受@ekhumoro的启发,我参考了大量的QT文档,发现QT中有许多不同的连接类型。了解这些类型,一切都很清楚 替换上述代码:
dlg.ForceTermimateSignal.connect(testThread.finished)
与:
然后,一切正常。谢谢你,我已经测试了你的方法,很有效。但我仍然会试图找到一种通过信号发射同步调用跨线程插槽的方法,如果不行,我会接受这个答案。
dlg.ForceTermimateSignal.connect(teshThread.finished, type=Qt.DirectConnection)