状态机框架程序设计

 Qt Widgets
时间:

状态机-说明

状态机框架提供了一些类来创建和执行状态图(state graphs),状态图为一个系统如何对外界激励进行反应提供了一个图形化模型,该模型是通过定义一些系统可能进入的状态以及系统从一个状态切换到另外一个状态来实现的。事件驱动的系统(比如Qt应用程序)的一个关键特性就是它的行为不仅仅依赖于最后一个或者当前的事件,而且也依赖于将要执行的事件。通过使用状态图,这些信息会非常容易表达。


状态机-demo

一个最简单的应用:假定状态机由一个QPushButton控制,包含3个状态:s1,s2,s3.其中s1是初始状态。当单击按钮时,状态切换到另一状态。

  • 源码demo

#include "widget.h"
#include <QApplication>
#include <QPushButton>
#include <QState>
#include <QStateMachine>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QPushButton button("State Machine");
    //创建状态机和3个状态,并将3个状态添加到状态机中
    QStateMachine machine;
    QState * s1 = new QState(&machine);
    QState * s2 = new QState(&machine);
    QState * s3 = new QState(&machine);
    //为按钮部件的geometry属性分配一个值,当进入该状态时会设置该值
    s1->assignProperty(&button, "geometry", QRect(100, 100, 120, 50));
    s2->assignProperty(&button, "geometry", QRect(300, 100, 120, 50));
    s3->assignProperty(&button, "geometry", QRect(200, 200, 120, 50));
    //使用按钮部件的单击信号来完成3个状态的切换
    s1->addTransition(&button, SIGNAL(clicked()), s2);
    s2->addTransition(&button, SIGNAL(clicked()), s3);
    s3->addTransition(&button, SIGNAL(clicked()), s1);
    //设置状态机的初始状态并启动状态机
    machine.setInitialState(s1);
    machine.start();
    button.show();
    return a.exec();
}

说明: 要使用一个状态机,则需要先创建该状态机和使用到的状态,可以像这里在创建状态时直接将其添加到状态机中,也可以使用QStateMachine::addState()来添加状态。

  • 创建完状态后要使用assignProperty()函数为QObject对象的属性分配值。这样在进入该状态时就可以为QObject对象的这个属性设置该值。
  • 然后要使用addTransition()函数来完成一个状态到另一个状态的切换,可以关联QObject对象的一个信号来触发切换。
  • 最后要为状态机设置初始状态并启动状态机,这样当状态机启动时就会自动进入初始状态,状态机是异步执行的,它会成为应用程序事件循环的一部分。

  • 当状态机进入一个状态会发射QState::entered()信号,而退出一个状态时会发射QState::exited()信号。可以关联这两个信号来完成一些操作。例如进入s3状态时将按钮最小化,那么可以在程序中调用setlnitialState()函数,并在代码前添加:
QObject::connect(s3, &QState::entered, &button, &QPushButton::showMinimized);

0 评论