我一直在使用Qt中的线程,在测试另一个线程中对象的信号时,我遇到了无法解释的行为。
上下文:
import threading
from PyQt5.QtCore import QObject, QThread
class MyObject(QObject):
def __init__(self):
super(MyObject, self).__init__()
print 'obj init, thread id: {}'.format(threading.current_thread().ident)
print 'obj init, thread affinity: {}'.format(self.thread())
def print_thread_id(self):
print 'thread id: {}'.format(threading.current_thread().ident)
print 'thread affinity: {}'.format(self.thread())
obj = MyObject()
thread = QThread()
# thread.started.connect(obj.print_thread_id)
obj.moveToThread(thread)
thread.started.connect(obj.print_thread_id)
thread.start()
print 'thread started'
所以我们有一个QObject,它在一个主线程中初始化,然后移动到一个工作线程。我们想检查新的线程ID,并且线程亲和力已经改变。
如果我们在thread.started
之后连接obj.moveToThread()
信号,我们可以看到线程ID和线程关联的新值:
obj init, thread id: 3296
obj init, thread affinity: <PyQt5.QtCore.QThread object at 0x0000000004819D38>
thread started
thread id: 20040
thread affinity: <PyQt5.QtCore.QThread object at 0x0000000004819318>
但是如果我们在将print_thread_id
移动到工作线程之前尝试将信号连接到obj
,那么似乎不会发出信号:
obj init, thread id: 3296
obj init, thread affinity: <PyQt5.QtCore.QThread object at 0x0000000004819D38>
thread started
为什么呢?在moveToThread()
期间QObject究竟发生了什么以及它如何影响信号和插槽?
更新
不确定它是否相关,但是当创建obj
的主线程不是Qt GUI线程时,会观察到所描述的行为。如果我们在Qt GUI线程中做同样的事情:
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
obj = MyObject()
thread = QThread()
thread.started.connect(obj.print_thread_id)
obj.moveToThread(thread)
thread.start()
print 'thread started'
发出信号,但结果出乎意料:
obj init, thread id: 4592
obj init, thread affinity: <PyQt5.QtCore.QThread object at 0x0000000007DF0CA8>
thread started
thread id: 4592
thread affinity: <PyQt5.QtCore.QThread object at 0x0000000007DF0CA8>
线程ID和线程关联性与创建对象实例时相同。看起来该对象未被移动到工作线程。