Qt中状态机框架测试


环境:

主机: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]
  1. #ifndef WIDGET_H   
  2. #define WIDGET_H   
  3.   
  4. #include <QWidget>   
  5. #include <QStackedWidget>   
  6. #include <QDebug>   
  7. #include <QTimer>   
  8. #include <unistd.h>   
  9. #include <sys/types.h>   
  10. #include <fcntl.h>   
  11. #include <sys/stat.h>   
  12. #include <stdio.h>   
  13. #include <sys/param.h>   
  14. #include <QVector>   
  15. #include <QByteArray>   
  16. #include <QQueue>   
  17. #include <QSemaphore>   
  18. #include <iostream>   
  19. #include <QFile>   
  20. #include "QThread"   
  21. #include <QtGui>   
  22. #include <QMutex>   
  23. #include <QtNetwork>   
  24. #include <QUdpSocket>   
  25. #include <sys/ioctl.h>   
  26. #include <stdlib.h>   
  27. #include <stdio.h>   
  28. #include <linux/soundcard.h>   
  29. #include <alsa/asoundlib.h>   
  30. #include <QtGui/QMainWindow>   
  31. #include <QtGui/QDialog>   
  32. #include <QtGui/QPushButton>   
  33. #include <QtGui/QHBoxLayout>   
  34. #include <QtGui/QVBoxLayout>   
  35. #include <QtGui/QGridLayout>   
  36. #include <QTextCodec>   
  37. #include <QtGui/QToolButton>   
  38. #include <qsocketnotifier.h>   
  39. #include <QTimer>   
  40. #include <QtNetwork/QUdpSocket>   
  41. #include <iostream>   
  42. #include <qmessagebox.h>   
  43. #include <qstringlist.h>   
  44. #include <QSound>   
  45. #include <sys/socket.h>   
  46. #include <arpa/inet.h>   
  47. #include <QMap>   
  48. #include <linux/soundcard.h>   
  49. #include <netinet/in.h>   
  50. #include <netinet/ip.h>   
  51. #include <netinet/ip_icmp.h>   
  52. #include <netdb.h>   
  53. #include <QHostAddress>   
  54. #include <QStateMachine>   
  55. #include <QState>   
  56.   
  57. using namespace std;  
  58.   
  59. namespace Ui {  
  60.     class Widget;  
  61. }  
  62.   
  63. class Widget : public QWidget  
  64. {  
  65.     Q_OBJECT  
  66.   
  67. public:  
  68.     explicit Widget(QWidget *parent = 0);  
  69.     ~Widget();  
  70.   
  71.     QStateMachine machine;                  //状态机   
  72.     QState *s1;  
  73.     QState *s2;  
  74.     QState *s21;  
  75.     QState *s22;  
  76.     QState *s3;  
  77.   
  78. private:  
  79.     Ui::Widget *ui;  
  80.   
  81. private slots:  
  82.     void slot_s1_in();  
  83.     void slot_s1_out();  
  84.     void slot_s21_in();  
  85.     void slot_s21_out();  
  86.     void slot_s22_in();  
  87.     void slot_s22_out();  
  88.     void slot_s3_in();  
  89.     void slot_s3_out();  
  90.   
  91.     void slot_s2_in();  
  92.     void slot_s2_out();  
  93. };  
  94.   
  95. #endif // WIDGET_H  
widget.c:

[cpp]
  1. #include "widget.h"   
  2. #include "ui_widget.h"   
  3. //状态迁移   
  4. /* 
  5. s1  - KEY1 -> s21 
  6. s21 - KEY2 -> s22 
  7. s22 - KEY1 -> s3 
  8. s3  - KEY2 -> s1 
  9. */  
  10.   
  11. Widget::Widget(QWidget *parent) :  
  12.     QWidget(parent),  
  13.     ui(new Ui::Widget)  
  14. {  
  15.     ui->setupUi(this);  
  16.   
  17.     //状态初始化   
  18.     s1 = new QState();  
  19.     s2 = new QState();  
  20.     s21 = new QState(s2);  
  21.     s22 = new QState(s2);  
  22.     s3 = new QState();  
  23.     //s21状态设置初始子状态   
  24.     s2->setInitialState(s21);  
  25.     //将状态添加到状态机   
  26.     machine.addState(s1);  
  27.     machine.addState(s2);  
  28.     machine.addState(s3);  
  29.     //设置初始状态   
  30.     machine.setInitialState(s1);  
  31.     //定义状态机迁移   
  32.     s1->addTransition(ui->KEY1,SIGNAL(clicked()),s21);  
  33.     s21->addTransition(ui->KEY2,SIGNAL(clicked()),s22);  
  34.     s22->addTransition(ui->KEY1,SIGNAL(clicked()),s3);  
  35.     s3->addTransition(ui->KEY2,SIGNAL(clicked()),s1);  
  36.     //连接状态机和处理函数   
  37.     connect(s1,SIGNAL(entered()),this,SLOT(slot_s1_in()));  
  38.     connect(s21,SIGNAL(entered()),this,SLOT(slot_s21_in()));  
  39.     connect(s22,SIGNAL(entered()),this,SLOT(slot_s22_in()));  
  40.     connect(s3,SIGNAL(entered()),this,SLOT(slot_s3_in()));  
  41.   
  42.     connect(s1,SIGNAL(exited()),this,SLOT(slot_s1_out()));  
  43.     connect(s21,SIGNAL(exited()),this,SLOT(slot_s21_out()));  
  44.     connect(s22,SIGNAL(exited()),this,SLOT(slot_s22_out()));  
  45.     connect(s3,SIGNAL(exited()),this,SLOT(slot_s3_out()));  
  46.   
  47.     connect(s2,SIGNAL(entered()),this,SLOT(slot_s2_in()));  
  48.     connect(s2,SIGNAL(exited()),this,SLOT(slot_s2_out()));  
  49.     //开启状态机   
  50.     machine.start();  
  51. }  
  52.   
  53. void Widget::slot_s1_in()  
  54. {  
  55.     qDebug() << "s1 in";  
  56. }  
  57.   
  58. void Widget::slot_s1_out()  
  59. {  
  60.     qDebug() << "s1 out";  
  61. }  
  62.   
  63. void Widget::slot_s21_in()  
  64. {  
  65.     qDebug() << "s21 in";  
  66. }  
  67.   
  68. void Widget::slot_s21_out()  
  69. {  
  70.     qDebug() << "s21 out";  
  71. }  
  72.   
  73. void Widget::slot_s22_in()  
  74. {  
  75.     qDebug() << "s22 in";  
  76. }  
  77.   
  78. void Widget::slot_s22_out()  
  79. {  
  80.     qDebug() << "s22 out";  
  81. }  
  82.   
  83. void Widget::slot_s3_in()  
  84. {  
  85.     qDebug() << "s3 in";  
  86. }  
  87.   
  88. void Widget::slot_s3_out()  
  89. {  
  90.     qDebug() << "s3 out";  
  91. }  
  92.   
  93. void Widget::slot_s2_in()  
  94. {  
  95.     qDebug() << "s2 in";  
  96. }  
  97.   
  98. void Widget::slot_s2_out()  
  99. {  
  100.     qDebug() << "s2 out";  
  101. }  
  102.   
  103. Widget::~Widget()  
  104. {  
  105.     delete ui;  
  106. }  
说明:

测试发现,进子状态,首先先进父状态,跳转到其他状态,则会先退出当前子状态,然后再退出父状态.

相关内容