Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么QDialog中发出的信号不能调用QThread中连接的插槽?_Python_Pyside - Fatal编程技术网

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)