首页 Qt系列2:状态机框架介绍
文章
取消

Qt系列2:状态机框架介绍

分层状态机

大状态机包含小状态机,小状态机里面有各种状态。小状态机作为一个整体。

下面介绍一下Qt状态机框架

状态之间的转换可以由信号触发

相关类:

1
2
3
4
5
6
7
8
QHistoryState Means of returning to a previously active substate 返回先前活动子状态的方法

QStateMachineHierarchical 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))

elesos

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

欢迎交流

本文由作者按照 CC BY 4.0 进行授权