Qt状态机框架的一个典型应用

       本文通过一个典型的状态机模型,来说明如何在Qt中使用状态机.

       该模型有两个状态S1和S2,其中S1又有两个子状态S11和S12,S1为状态机的初始状态,S11为S1的初始状态.为了模拟一些嵌入式开发中的需要,在s12中启动了一个定时器,在S2中建立了一个模式对话框.

Qt状态机框架的一个典型应用_第1张图片

       对于一个确定的状态,其进入和退出时会分别发射entered()信号和exited()信号,你可以通过connect函数将该信号连接到自定义的状态入口和出口函数,而在进入一个确定的状态时,一般在其入口函数处初试化其状态.当从一个状态迁移到另一个状态时,它会先退出自身,然后退出其父状态(如果有父的话),然后在进入另一个状态.

       关于状态迁移,子状态会自动继承父状态的transition.因此,你不需要为每个子状态(如s11和s12)都添加一个transition,而只需要为它们的父状态添加一个transition就可以了.

       需要明确一点,在一个子状态中,不建议使用阻塞函数(比如模式对话框),因为你一旦引入阻塞,将会打断诸如定时器等发出的信号,将使状态机无法响应,当然,特殊的情况例外.

       好了,看代码

      

MyStateMachine::MyStateMachine(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MyStateMachine)
{
    ui->setupUi(this);

    timer = new QTimer;

    machine = new QStateMachine();
    s1 =new QState();
    s11 = new QState(s1);
    s12 = new QState(s1);
    s2 = new QState();
    machine->addState(s1);
    machine->addState(s2);
    machine->setInitialState(s1);

    //状态1的入口和出口
    QObject::connect(s1, SIGNAL(entered()), this, SLOT(s1_in()));
    QObject::connect(s1, SIGNAL(exited()), this, SLOT(s1_out()));

    //状态11的入口和出口
    QObject::connect(s11, SIGNAL(entered()), this, SLOT(s11_in()));
    QObject::connect(s11, SIGNAL(exited()), this, SLOT(s11_out()));

    //状态12的入口和出口
    QObject::connect(s12, SIGNAL(entered()), this, SLOT(s12_in()));
    QObject::connect(s12, SIGNAL(exited()), this, SLOT(s12_out()));

    //状态2的入口和出口
    QObject::connect(s2, SIGNAL(entered()), this, SLOT(s2_in()));
    QObject::connect(s2, SIGNAL(exited()), this, SLOT(s2_out()));

    //状态转移条件
    s11->addTransition(ui->pushButton, SIGNAL(pressed()), s12);
    s12->addTransition(ui->pushButton, SIGNAL(released()), s11);

    s1->addTransition(timer, SIGNAL(timeout()), s2);
    s2->addTransition(timer, SIGNAL(timeout()), s1);

    s1->setInitialState(s11);

    machine->start();
}

MyStateMachine::~MyStateMachine()
{
    delete ui;
}

void MyStateMachine::s1_in()
{
    qDebug("->s1_in");
}

void MyStateMachine::s1_out()
{
    qDebug("->s1_out");
}

void MyStateMachine::s11_in()
{
    qDebug("->s11_in");
}

void MyStateMachine::s11_out()
{
    qDebug("->s11_out");
}

void MyStateMachine::s12_in()
{
    qDebug("->s12_in");
    timer->start(1000*5);
}

void MyStateMachine::s12_out()
{
    qDebug("->s12_out");
}

void MyStateMachine::s2_in()
{
    qDebug("->s2_in");

    QMessageBox::warning(this, tr("Warning"),tr("Please Check System.\n"),QMessageBox::Save,QMessageBox::Save);
}

void MyStateMachine::s2_out()
{
    qDebug("->s2_out");
}
 

       本次实验的工程文件: StateMachine.tar.bz2

你可能感兴趣的:(Qt)