pyqt signal not emitted when button is clicked after move to QThread
-
Essentially I have a procedure, that will start upon the button click. Once I start the procedure, everything works fine, until the user input is required. However, when the user clicks the button, no 'clicked' signal is emitted. Signal is connected to slot appropriately. Button click stoped working after I moved the code to QThread.
class Procedure(QObject): def __init__(self, parent): super().__init__() self.parent = parent self.parent.button_a.clicked.connect(self.on_button_a_clicked) self.event = threading.Event() def run(self): # started running, doing some stuff here # waits for button click, i.e. when button is clicked, the event is set and then you may proceed self.event.wait() # NEVER REACHES HERE def on_button_a_clicked(self): self.event.set() class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super(MainWindow, self).__init__() self.setupUi(self) self.setFixedSize(self.size()) self.start_button.clicked.connect(self.on_start_clicked) def on_start_clicked(self): self.thread = QThread() self.worker = Procedure(self) self.worker.moveToThread(self.thread) self.thread.started.connect(self.worker.run) self.thread.start() def main(): app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() app.exec_() if __name__ == '__main__': main()
However, I do have an indication, that the signal is connected to slot appropriately, as when in function run() I manually emit the signal, the button click is emulated successfully. Therefore, I presume that the issue is that button click is not registered appropriately.
def run(self): # started running, doing some stuff here # following line successfully emulates the button click self.parent.button_a.clicked.emit() self.event.wait() # reaches here successfully
I also presume that this has something to do with QThread, since the issue appeared after I started to run my procedure in a QThread and all of the buttons that are related to main window function well, but I am kind of lost in the woods here and I am not sure how to debug this issue. Thank you in advance.
-
@JokZiz1 said in pyqt signal not emitted when button is clicked after move to QThread:
when the user clicks the button, no 'clicked' signal is emitted
Which button do you mean? You have two.
Also, why does child Procedure connect parents signal? This is bad design! Child should not know anything about parent. Such connections should be done by parent. I mean this connection:self.parent.button_a.clicked.connect(self.on_button_a_clicked)
-
@jsulm said in pyqt signal not emitted when button is clicked after move to QThread:
@JokZiz1 said in pyqt signal not emitted when button is clicked after move to QThread:
when the user clicks the button, no 'clicked' signal is emitted
Which button do you mean? You have two.
The button called 'button_a' does not work. The button that starts the thread does work.
Moving signal-slot connection from child to parent did not solve the issue
-
@jsulm said in pyqt signal not emitted when button is clicked after move to QThread:
@JokZiz1 Please show how you're connecting button_a.clicke now. The slot should be called if connect() succeeds.
If you would have read what I have initially written, the signal is connected to slot appropriately, because if I manually in the code emit the clicked signal, it is reached then.
Anyway, the changes I have made
class Procedure(QObject): def __init__(self, parent): super().__init__() self.parent = parent self.event = threading.Event() def run(self): # started running, doing some stuff here # waits for button click, i.e. when button is clicked, the event is set and then you may proceed self.event.wait() # NEVER REACHES HERE def on_button_a_clicked(self): print("reached here") self.event.set() class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super(MainWindow, self).__init__() self.setupUi(self) self.setFixedSize(self.size()) self.start_button.clicked.connect(self.on_start_clicked) def on_start_clicked(self): self.thread = QThread() self.worker = Procedure(self) self.worker.moveToThread(self.thread) self.thread.started.connect(self.worker.run) self.button_a.clicked.connect(self.worker.on_button_a_clicked) self.thread.start() def main(): app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() app.exec_() if __name__ == '__main__': main()