QT中状态机框架测试
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
环境:
主机:Fedora12
开发软件:QT
目标板:OK6410-A
实现功能:
两个按键KEY1,KEY2,产生状态迁移动作,3个状态:s1,s2,s3.其中s2又有2个子状态:s21,s22.
触发关系:
s1 - KEY1 -> s21 s21 - KEY2 -> s22 s22 - KEY1 -> s3 s3 - KEY2 -> s1 |
源代码:
widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QStackedWidget>
#include <QDebug>
#include <QTimer>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/param.h>
#include <QVector>
#include <QByteArray>
#include <QQueue>
#include <QSemaphore>
#include <iostream>
#include <QFile>
#include "QThread"
#include <QtGui>
#include <QMutex>
#include <QtNetwork>
#include <QUdpSocket>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/soundcard.h>
#include <alsa/asoundlib.h>
#include <QtGui/QMainWindow>
#include <QtGui/QDialog>
#include <QtGui/QPushButton>
#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>
#include <QtGui/QGridLayout>
#include <QTextCodec>
#include <QtGui/QToolButton>
#include <qsocketnotifier.h>
#include <QTimer>
#include <QtNetwork/QUdpSocket>
#include <iostream>
#include <qmessagebox.h>
#include <qstringlist.h>
#include <QSound>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <QMap>
#include <linux/soundcard.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <QHostAddress>
#include <QStateMachine>
#include <QState>
using namespace std;
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
QStateMachine machine; //状态机
QState *s1;
QState *s2;
QState *s21;
QState *s22;
QState *s3;
private:
Ui::Widget *ui;
private slots:
void slot_s1_in();
void slot_s1_out();
void slot_s21_in();
void slot_s21_out();
void slot_s22_in();
void slot_s22_out();
void slot_s3_in();
void slot_s3_out();
void slot_s2_in();
void slot_s2_out();
};
#endif // WIDGET_H
widget.c:
#include "widget.h"
#include "ui_widget.h"
//状态迁移
/*
s1 - KEY1 -> s21
s21 - KEY2 -> s22
s22 - KEY1 -> s3
s3 - KEY2 -> s1
*/
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//状态初始化
s1 = new QState();
s2 = new QState();
s21 = new QState(s2);
s22 = new QState(s2);
s3 = new QState();
//s21状态设置初始子状态
s2->setInitialState(s21);
//将状态添加到状态机
machine.addState(s1);
machine.addState(s2);
machine.addState(s3);
//设置初始状态
machine.setInitialState(s1);
//定义状态机迁移
s1->addTransition(ui->KEY1,SIGNAL(clicked()),s21);
s21->addTransition(ui->KEY2,SIGNAL(clicked()),s22);
s22->addTransition(ui->KEY1,SIGNAL(clicked()),s3);
s3->addTransition(ui->KEY2,SIGNAL(clicked()),s1);
//连接状态机和处理函数
connect(s1,SIGNAL(entered()),this,SLOT(slot_s1_in()));
connect(s21,SIGNAL(entered()),this,SLOT(slot_s21_in()));
connect(s22,SIGNAL(entered()),this,SLOT(slot_s22_in()));
connect(s3,SIGNAL(entered()),this,SLOT(slot_s3_in()));
connect(s1,SIGNAL(exited()),this,SLOT(slot_s1_out()));
connect(s21,SIGNAL(exited()),this,SLOT(slot_s21_out()));
connect(s22,SIGNAL(exited()),this,SLOT(slot_s22_out()));
connect(s3,SIGNAL(exited()),this,SLOT(slot_s3_out()));
connect(s2,SIGNAL(entered()),this,SLOT(slot_s2_in()));
connect(s2,SIGNAL(exited()),this,SLOT(slot_s2_out()));
//开启状态机
machine.start();
}
void Widget::slot_s1_in()
{
qDebug() << "s1 in";
}
void Widget::slot_s1_out()
{
qDebug() << "s1 out";
}
void Widget::slot_s21_in()
{
qDebug() << "s21 in";
}
void Widget::slot_s21_out()
{
qDebug() << "s21 out";
}
void Widget::slot_s22_in()
{
qDebug() << "s22 in";
}
void Widget::slot_s22_out()
{
qDebug() << "s22 out";
}
void Widget::slot_s3_in()
{
qDebug() << "s3 in";
}
void Widget::slot_s3_out()
{
qDebug() << "s3 out";
}
void Widget::slot_s2_in()
{
qDebug() << "s2 in";
}
void Widget::slot_s2_out()
{
qDebug() << "s2 out";
}
Widget::~Widget()
{
delete ui;
}
说明:
测试发现,进子状态,首先先进父状态,跳转到其他状态,则会先退出当前子状态,然后再退出父状态.