原创文章,可以转载,转载时请以超链接形式保留本文地址、作者信息和本声明。否则将追究法律责任。
前几节讲述的都是状态机运行的过程,没有结束状态。任何一个状态机都应该有一个结束状态。那如何停止状态机呢,或者说如何进入终止态呢?
Qt状态机框架中,有一个特殊的类QFinalState,这个类定义了状态机的终止状态,我们仅需要简单的将QFinalState的对象A加入到状态机中,然后定义一个状态迁移到该A就可以终止状态机了。状态机在终止时会触发QStateMachine::finished()信号,我们可以根据该信号做一些“文章”。我们声明一个OnHalt()槽函数,关联QStateMachine::finished()信号,看代码:
声明:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QStateMachine>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void OnExitStateS1(void);
void OnEnterStateS2(void);
void OnHalt(void);
private:
Ui::MainWindow *ui;
QStateMachine machine;
};
实现:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QState>
#include <QDebug>
#include <QFinalState>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QState *s1 = new QState();
QState *s2 = new QState();
QState *s3 = new QState();
QFinalState *final = new QFinalState();
machine.addState(s1);
machine.addState(s2);
machine.addState(s3);
machine.addState(final);
s1->addTransition(ui->button, SIGNAL(clicked()), s2);
s2->addTransition(ui->button, SIGNAL(clicked()), s3);
s3->addTransition(ui->button, SIGNAL(clicked()), final);
// 分配属性
s1->assignProperty(ui->button, "text", "S1");
s2->assignProperty(ui->button, "text", "S2");
s3->assignProperty(ui->button, "text", "S3");
connect(s1, SIGNAL(exited()), this, SLOT(OnExitStateS1()));
connect(s2, SIGNAL(entered()), this, SLOT(OnEnterStateS2()));
connect(&machine, SIGNAL(finished()), this, SLOT(OnHalt()));
machine.setInitialState(s1);
machine.start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::OnExitStateS1(void)
{
qDebug() << "Exit s1";
}
void MainWindow::OnEnterStateS2(void)
{
qDebug() << "Enter s2";
}
void MainWindow::OnHalt(void)
{
qDebug() << "State Machine Halted";
}
运行上述代码,当点击到S3时,再此点击,状态机终止,输出"State Machine Halted"字符串。