分层状态机
大状态机包含小状态机,小状态机里面有各种状态。小状态机作为一个整体。
下面介绍一下Qt状态机框架
状态之间的转换可以由信号触发
相关类:
1
2
3
4
5
6
7
8
QHistoryState :Means of returning to a previously active substate 返回先前活动子状态的方法
QStateMachine:Hierarchical finite state machine 分层有限状态机
s1->addTransition(button, &QPushButton::clicked, s2); //转换可以将任何状态作为目标,不必与源状态位于同一层级。
machine.addState(s1);
machine.setInitialState(s1);
machine.start();
可以在状态进入和退出时执行一些操作:
1
2
3
s1->assignProperty(label, "text", "In state s1");
QObject::connect(s3, &QState::entered, button, &QPushButton::showMaximized);
QObject::connect(s3, &QState::exited, button, &QPushButton::showMinimized);
Custom states可以重新实现QAbstractState::onEntry() 和QAbstractState::onExit()
为了使状态机结束,需要一个最终状态(QFinalState)。
可对状态进行分组,分组后的状态可以作为一个整体进行转换。通过指定父状态即可:
1
QState *s11 = new QState(s1);
使用历史状态保存和恢复当前状态
1
2
3
QHistoryState 代表父状态退出时父状态所处的子状态。
QHistoryState *s1h = new QHistoryState(s1);
s3->addTransition(s1h);
使用并行状态避免状态组合爆炸
1
2
3
4
QState *s1 = new QState(QState::ParallelStates);
// s11 and s12 will be entered in parallel
QState *s11 = new QState(s1);
QState *s12 = new QState(s1);
检查组合状态是否结束
子状态可以是最终状态,当进入最终子状态时,它的父状态会发出QState::finished()信号
1
s1->addTransition(s1, &QState::finished, s2);
没有目标的Transition
不会改变状态,这可以让我们不必离开该状态
1
2
3
QSignalTransition *trans = new QSignalTransition(&button, &QPushButton::clicked);
QObject::connect(trans, QSignalTransition::triggered, &msgBox, &QMessageBox::exec);//单击按钮时都会显示消息框
s1->addTransition(trans);保持当前状态s1
Events, Transitions and Guards
状态机有自己的事件循环,你可以使用QStateMachine::postEvent()将自己的事件发布到状态机。
QEvent(QEvent::Type(QEvent::User+1))
1
2
3
4
5
StringTransition *t1 = new StringTransition("Hello");
s1->addTransition(t1);
t1->setTargetState(s2);
然后发送事件给状态机
machine.postEvent(new StringEvent("Hello"));
使用恢复策略自动恢复属性
machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties);
置此后将自动恢复所有属性,或者恢复到父状态的属性
动画属性分配
1
2
QSignalTransition *transition = s1->addTransition(button, &QPushButton::clicked, s2);
transition->addAnimation(new QPropertyAnimation(button, "geometry"));
如果状态机的全局恢复策略设置为QStateMachine::RestoreProperties,还可以为属性恢复添加动画。
检测All Properties Have Been Set In A State
s2->addTransition(s2, &QState::propertiesAssigned, s3);//比如有动画时,动画结束才会进入s3
嵌套状态机
QStateMachine是一个子类QState。这允许状态机成为另一台机器的子状态
参考
https://doc.qt.io/qt-5/statemachine-api.html
欢迎交流