環境:
主機:Fedora 12
開發軟件: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:
[cpp]
- #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:
[cpp]
- #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;
- }
說明:
測試發現,進子狀態,首先先進父狀態,跳轉到其他狀態,則會先退出當前子狀態,然後再退出父狀態.