我一直在努力让状态机在 PySide6 中工作,我刚刚发现了一个令人厌恶的 hack 让它工作。我正在尝试让按钮在状态之间切换。如果我正常设置它,状态机甚至永远不会进入其初始状态,并且永远不会进行任何转换。但是,如果我将一个函数连接到按钮的
clicked
信号,仅打印出 machine.configuration()
,状态机会突然开始工作。
我已在以下文件中复制了此行为:
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())
该行未注释(期望的行为) 注释掉该行(错误行为) 如果倒数第二行未注释,则 QLabel 将正确设置为“状态 1”,并且机器可以正确工作和转换。如果它被注释,机器甚至永远不会启动,并且 QLabel 会显示“Hello World!”。最后评论的语句没有任何作用。
有人知道是否应该报告此问题,以及是否可以通过比此更简单的修复来解决此问题?在我的应用程序中,我有超过 60 个信号,将每个信号连接到这样一个函数将是一种疯狂的资源浪费。
我使用的是PySide6.7.0
我找到了更好的创可贴修复方法。
machine.setInitialState(s1)
machine.start()
button = QPushButton("Click me!")
button.clicked.connect(lambda: print("Current state:", machine.configuration()))
通过创建一个按钮(不添加到布局)并将其单击信号连接到
machine.configuration()
,这会以某种方式使状态机开始运行。这不是一个完美的修复,但它相对干净和简单。