This is a followup-question based on ekhumoro's answers here and here.
I thought to understand, that when a slot is correctly defined with pyqtSlot
and assigned to QThread
(e.g. with moveToThread()
), it will be executed in this QThread and not the calling one. Furthermore, making the connection with Qt.QueuedConnection
or Qt.AutoConnection
is also required.
I wrote Code to test this. My goal is to achive something quite simple like this:
Gui with a button, that starts some time-consuming-work and return with a result to display back in the GUI.
from PyQt5.Qt import *
class MainWindow(QMainWindow):
change_text = pyqtSignal(str)
def __init__(self):
super().__init__()
self.button = QPushButton('Push me!', self)
self.setCentralWidget(self.button)
print('main running in:', QThread.currentThread())
thread = Thread(change_text, self)
thread.start()
self.button.clicked.connect( thread.do_something_slow, Qt.QueuedConnection)
self.change_text.connect(self.display_changes, Qt.QueuedConnection)
@pyqtSlot(str)
def display_changes( self, text ):
self.button.setText(text)
class Thread(QThread):
def __init__(self, signal_to_emit, parent):
super().__init__(parent)
self.signal_to_emit = signal_to_emit
#self.moveToThread(self) #doesn't help
@pyqtSlot()
def do_something_slow( self ):
print('Slot doing stuff in:', QThread.currentThread())
import time
time.sleep(5)
self.signal_to_emit.emit('I did something')
if __name__ == '__main__':
app = QApplication([])
main = MainWindow()
main.show()
app.exec()
But .. the gui is blocking and the slot is called in the main-thread.
What am I missing? Have to be something small (I hope).