I’ve been struggling to get a state machine working in PySide6, and I just found a disgusting hack to get it to work. I’m trying to have a button fire transitions between states. If I set it up normally, the state machine never even enters its initial state, and never does any transitions. However, If I connect a function to the button’s clicked
signal that just prints out machine.configuration()
, the state machine suddenly works.
I’ve replicated this behavior in the following file:
from PySide6.QtStateMachine import QStateMachine, QState
from PySide6.QtWidgets import QMainWindow, QLabel, QPushButton, QVBoxLayout, QWidget
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Base Node")
self.setFixedSize(480, 480)
q_button = QPushButton("Click me!")
q_label = QLabel("Hello World!")
layout = QVBoxLayout()
layout.addWidget(q_label)
layout.addWidget(q_button)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
machine = QStateMachine()
# Define states
s1 = QState()
s2 = QState()
s3 = QState()
# When entering state, change the stacked widget index
s1.assignProperty(q_label, "text", "State 1")
s2.assignProperty(q_label, "text", "State 2")
s3.assignProperty(q_label, "text", "State 3")
# Define transitions. The signals are emitted by the widgets when clicked in certain corners of the screen
s1.addTransition(q_button.clicked, s2)
s2.addTransition(q_button.clicked, s3)
s3.addTransition(q_button.clicked, s1)
machine.addState(s1)
machine.addState(s2)
machine.addState(s3)
machine.setInitialState(s1)
machine.start()
q_button.clicked.connect(lambda : print("Current state:", machine.configuration()))
#print("Current state:", machine.configuration())
With the line uncommented (desired behavior)
With the line commented (wrong behavior)
If the 2nd-to-last line is left uncommented, the QLabel is correctly set to “State 1”, and the machine works & transitions correctly. If it is commented, the machine never even starts, and the QLabel reads “Hello World!”. The last commented statement has no effect.
Anyone know whether this should be reported, and whether this can be fixed with a fix less hacky than this one? In my application, I have well over 60 signals, and it would be an insane waste of resources to connect each one to such a function.
I am using PySide6.7.0