I'm trying to implement a state machine in my GUI (using python3.8 and Qt5 (using PyQt5 and not PySides!)). The problem I encounter with this is when adding a transistion based on an event.
Using the code below, the interpreter complains at line 26:
s1.addTransition(self.btn_start, pyqtSignal("clicked()"), s2)
TypeError: C++ type 'clicked()' is not supported as a pyqtSignal() type argument type
import sys
import logging
from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout, QApplication
from PyQt5.QtCore import QStateMachine, QState, QFinalState, pyqtSignal
class TabTest(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.logger = logging.getLogger("TABTEST")
self.btn_start = QPushButton("START")
# self.btn_start.clicked.connect(self.btn_start_clicked)
layout = QVBoxLayout()
layout.addWidget(self.btn_start)
self.setLayout(layout)
machine = QStateMachine()
s1 = QState()
s1.assignProperty(self.btn_start, "TEXT", "CLICK ME")
s2 = QFinalState()
s1.addTransition(self.btn_start, pyqtSignal("clicked()"), s2)
machine.addState(s1)
machine.addState(s2)
machine.setInitialState(s1)
machine.start()
# def btn_start_clicked(self):
# self.logger.info("klikked")
if __name__ == "__main__":
app = QApplication(sys.argv)
main_window = TabTest()
main_window.show()
sys.exit(app.exec_())
I googled before and read on stackoverflow but all answers are for Qt4
or are using PySides
. Lots of changes between Qt5
and Qt4
.
And PySides
has PySides.QtCore.SIGNAL
, I found the equivalent in PyQt5
is PyQt5.QtCore.pyqtSignal
, but can't seem to have it working.
Your code has 3 errors:
QStateMachine is a local variable that will be destroyed instantly preventing the desired behavior from being observed, given that there are 2 solutions: set a parent(change to
QStateMachine(self)
) or make it a member of the class(change allmachine
toself.machine
).If you want to assign a property then the name must be respected, in this case the property is "text" and not "TEXT".
In PyQt5 you must pass the signal, that is,
obj.foo_signal
, in your caseself.btn_start.clicked
.Considering the above, the solution is: