这是我的代码:
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不能调用'完成'对象testThread的功能?
答案 0 :(得分:0)
当您将信号连接到同一线程中的插槽时,将直接并同步调用插槽。但是当连接是跨线程时,信号将作为事件发布,并且将异步调用插槽。
所以在你的例子中,这一行:
self.ForceTermimateSignal.emit()
将向对话框的事件队列添加信号事件,然后返回而不直接调用线程的finished
时隙。以下一行:
super(TestDialog, self).done(code)
然后将立即执行,这将在信号事件有机会被处理之前终止事件循环。
如果用以下代码替换发射线:
testThread.finished_flag = True
示例应该按预期工作。
答案 1 :(得分:0)
受@ekhumoro的启发,我提到了Signals and Slots Across Threads的QT文档,发现QT中有许多不同的连接类型。了解这些类型,一切都很清楚。
替换上面的代码:
dlg.ForceTermimateSignal.connect(testThread.finished)
使用:
dlg.ForceTermimateSignal.connect(teshThread.finished, type=Qt.DirectConnection)
然后,一切都按预期工作。