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

来源:互联网 发布:零速争霸玩具淘宝 编辑:程序博客网 时间:2024/05/21 10:29

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

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

       对于一个确定的状态,其进入和退出时会分别发射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

原创粉丝点击