I've been playing with threading in Qt and while testing signals for objects in another thread I faced the behaviour I can't explain.
Context:
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'
So we have a QObject, that is initialized in a main thread and then moved to a worker thread. We want to check new thread id and that thread affinity has changed.
If we connect a thread.started
signal afterobj.moveToThread()
we can see new values for thread id and thread affinity:
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>
But if we try to connect a signal to print_thread_id
before moving obj
to a worker thread, it seems that the signal is not emitted:
obj init, thread id: 3296
obj init, thread affinity: <PyQt5.QtCore.QThread object at 0x0000000004819D38>
thread started
Why? What exactly happens with a QObject during moveToThread()
and how it affects signals and slots?
Update:
Not sure if it's related, but the described behaviour is observed when the main thread where obj
is created is not a Qt GUI thread. If we do the same in a Qt GUI thread:
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'
than the signal is emitted, but the result is unexpected:
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>
Thread id and thread affinity are the same as when the object instance was created. It looks like the object was not moved to a worker thread.