PySide6的状态机模块提供了一种方便的方式来实现状态机模式,用于管理程序的状态和状态转换。通过使用PySide6的状态机模块,开发者可以更加清晰地组织程序逻辑,使程序更易于维护和扩展。
在PySide6中,状态机相关的类主要包括:
1. QState:表示一个状态,可以设置状态进入时执行的操作和离开时执行的操作。
2. QFinalState:表示最终状态,用于标识状态机的结束状态。
3. QStateMachine:表示状态机本身,可以管理多个状态和状态之间的转换。
4. QSignalTransition:表示基于信号的状态转换,可以在特定信号触发时实现状态之间的转换。
通过使用这些类,开发者可以创建和管理程序的状态机,定义状态之间的转换条件,并在状态转换时执行相应的操作。这样可以帮助开发者更好地控制程序的行为,提高程序的可维护性和可扩展性。
在PySide6中,状态机模块的使用与Qt中的类似,通过创建状态、添加状态到状态机、设置初始状态、建立状态转换等步骤来实现状态机的功能。开发者可以根据具体的需求和场景,灵活运用状态机模块来优化程序逻辑。
总的来说,PySide6的状态机模块为开发者提供了一个强大而灵活的工具,帮助管理复杂程序的状态和行为,使程序更加清晰和易于维护。下面先是个简单示例
import sys
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySide6.QtStateMachine import QState,QStateMachine,QFinalState,QSignalTransition
class Window(QWidget):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.init_buttons()
stop :QState = QState()
running :QState = QState()
pause :QState = QState()
#创建一个状态机
machine = QStateMachine(self)
#将状态添加到状态机
machine.addState(stop)
machine.addState(running)
machine.addState(pause)
#设置初始状态机状态
machine.setInitialState(stop)
#设置转换条件
stop_to_run = stop.addTransition(self.btn.clicked,running)
run_to_pause = running.addTransition(self.btn.clicked,pause)
pause_to_run = pause.addTransition(self.btn.clicked,running)
#可以触发的信号
run_to_pause.triggered.connect(lambda :print("pase状态触发了,可以写相关逻辑代码"))
#根据状态切换相对于的属性值
stop.assignProperty(self.lab2,'text',"stop state")
pause.assignProperty(self.lab2,'text',"pause state")
running.assignProperty(self.lab2,'text','running state')
#启动状态机
machine.start()
def init_buttons(self):
self.resize(300,300)
label = QLabel("当前状态:",self)
label.move(50,50)
self.lab2 = QLabel("",self)
self.lab2.setGeometry(150,50,80,20)
self.lab2.setStyleSheet("border:2px solid blue")
self.btn = QPushButton("click",self)
self.btn.move(200,200)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec())
上面代码使用PySide6实现了一个简单的状态机示例。在这个示例中,定义了三个状态:stop、running和pause,并设置了状态之间的转换条件。当点击按钮时,状态会按照设定的转换条件进行切换,并相应地修改一个label的文本内容以展示当前状态。
在代码中,首先创建了三个状态stop、running和pause,并将它们添加到状态机中。然后设置了初始状态为stop,并定义了状态之间的转换条件:从stop转换到running,从running转换到pause,从pause转换回running。
另外,通过assignProperty方法,根据状态的改变,修改了一个label的文本内容来展示当前状态。
最后,启动了状态机,并显示了一个窗口,包含一个label用于显示当前状态和一个按钮用于触发状态转换。
上面的状态机有一问题,就是永远在running 和 pause之间来回切换,显然这不是我们想要的。我们可以在增加一个复位按钮,当点击后,让状态机归为stop状态。这个很好实现
添加一个按钮
self.btn_reset = QPushButton("reset",self) self.btn_reset.move(100,200)
设置状态:
#复位状态机 running.addTransition(self.btn_reset.clicked,stop) pause.addTransition(self.btn_reset.clicked,stop)
完整代码如下:
import sys
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySide6.QtStateMachine import QState,QStateMachine,QFinalState,QSignalTransition
class Window(QWidget):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.init_buttons()
stop :QState = QState()
running :QState = QState()
pause :QState = QState()
#创建一个状态机
machine = QStateMachine(self)
#将状态添加到状态机
machine.addState(stop)
machine.addState(running)
machine.addState(pause)
#设置初始状态机状态
machine.setInitialState(stop)
#设置转换条件
stop_to_run = stop.addTransition(self.btn.clicked,running)
run_to_pause = running.addTransition(self.btn.clicked,pause)
pause_to_run = pause.addTransition(self.btn.clicked,running)
#复位状态机
running.addTransition(self.btn_reset.clicked,stop)
pause.addTransition(self.btn_reset.clicked,stop)
#可以触发的信号
run_to_pause.triggered.connect(lambda :print("pase状态触发了,可以写相关逻辑代码"))
#根据状态切换相对于的属性值
stop.assignProperty(self.lab2,'text',"stop state")
pause.assignProperty(self.lab2,'text',"pause state")
running.assignProperty(self.lab2,'text','running state')
#启动状态机
machine.start()
def init_buttons(self):
self.resize(300,300)
label = QLabel("当前状态:",self)
label.move(50,50)
self.lab2 = QLabel("",self)
self.lab2.setGeometry(150,50,80,20)
self.lab2.setStyleSheet("border:2px solid blue")
self.btn = QPushButton("click",self)
self.btn.move(200,200)
self.btn_reset = QPushButton("reset",self)
self.btn_reset.move(100,200)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec())
假如这个状态切换伴随着其他操作比如歌曲的播放和暂停,那在按钮按下时,需要对应的操作。对于按钮来说,都是click状态,怎么知道是谁切换到谁呢?可以通过判断标签的属性来确定,但更好的办法是不同的状态切换时直接触发对应的处理。
将stop的addTransition改造一下。 addTransition添加的参数可以是QSignalTransition类。QSignalTransition在初始化时,设置上关联的控件和控件动作。然后通过 setTargetState设置成将要变成的状态,通过triggered信号,来绑定触发时对应的行为(这里添加了一个槽函数)。再用stop状态添加新创建的QSignalTransition,完成状态切换的设置。未完待续。。。。