歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Qt中狀態機框架測試

Qt中狀態機框架測試

日期:2017/3/1 10:38:54   编辑:Linux編程

環境

主機: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. #include <QWidget>
  4. #include <QStackedWidget>
  5. #include <QDebug>
  6. #include <QTimer>
  7. #include <unistd.h>
  8. #include <sys/types.h>
  9. #include <fcntl.h>
  10. #include <sys/stat.h>
  11. #include <stdio.h>
  12. #include <sys/param.h>
  13. #include <QVector>
  14. #include <QByteArray>
  15. #include <QQueue>
  16. #include <QSemaphore>
  17. #include <iostream>
  18. #include <QFile>
  19. #include "QThread"
  20. #include <QtGui>
  21. #include <QMutex>
  22. #include <QtNetwork>
  23. #include <QUdpSocket>
  24. #include <sys/ioctl.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <linux/soundcard.h>
  28. #include <alsa/asoundlib.h>
  29. #include <QtGui/QMainWindow>
  30. #include <QtGui/QDialog>
  31. #include <QtGui/QPushButton>
  32. #include <QtGui/QHBoxLayout>
  33. #include <QtGui/QVBoxLayout>
  34. #include <QtGui/QGridLayout>
  35. #include <QTextCodec>
  36. #include <QtGui/QToolButton>
  37. #include <qsocketnotifier.h>
  38. #include <QTimer>
  39. #include <QtNetwork/QUdpSocket>
  40. #include <iostream>
  41. #include <qmessagebox.h>
  42. #include <qstringlist.h>
  43. #include <QSound>
  44. #include <sys/socket.h>
  45. #include <arpa/inet.h>
  46. #include <QMap>
  47. #include <linux/soundcard.h>
  48. #include <netinet/in.h>
  49. #include <netinet/ip.h>
  50. #include <netinet/ip_icmp.h>
  51. #include <netdb.h>
  52. #include <QHostAddress>
  53. #include <QStateMachine>
  54. #include <QState>
  55. using namespace std;
  56. namespace Ui {
  57. class Widget;
  58. }
  59. class Widget : public QWidget
  60. {
  61. Q_OBJECT
  62. public:
  63. explicit Widget(QWidget *parent = 0);
  64. ~Widget();
  65. QStateMachine machine; //狀態機
  66. QState *s1;
  67. QState *s2;
  68. QState *s21;
  69. QState *s22;
  70. QState *s3;
  71. private:
  72. Ui::Widget *ui;
  73. private slots:
  74. void slot_s1_in();
  75. void slot_s1_out();
  76. void slot_s21_in();
  77. void slot_s21_out();
  78. void slot_s22_in();
  79. void slot_s22_out();
  80. void slot_s3_in();
  81. void slot_s3_out();
  82. void slot_s2_in();
  83. void slot_s2_out();
  84. };
  85. #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. Widget::Widget(QWidget *parent) :
  11. QWidget(parent),
  12. ui(new Ui::Widget)
  13. {
  14. ui->setupUi(this);
  15. //狀態初始化
  16. s1 = new QState();
  17. s2 = new QState();
  18. s21 = new QState(s2);
  19. s22 = new QState(s2);
  20. s3 = new QState();
  21. //s21狀態設置初始子狀態
  22. s2->setInitialState(s21);
  23. //將狀態添加到狀態機
  24. machine.addState(s1);
  25. machine.addState(s2);
  26. machine.addState(s3);
  27. //設置初始狀態
  28. machine.setInitialState(s1);
  29. //定義狀態機遷移
  30. s1->addTransition(ui->KEY1,SIGNAL(clicked()),s21);
  31. s21->addTransition(ui->KEY2,SIGNAL(clicked()),s22);
  32. s22->addTransition(ui->KEY1,SIGNAL(clicked()),s3);
  33. s3->addTransition(ui->KEY2,SIGNAL(clicked()),s1);
  34. //連接狀態機和處理函數
  35. connect(s1,SIGNAL(entered()),this,SLOT(slot_s1_in()));
  36. connect(s21,SIGNAL(entered()),this,SLOT(slot_s21_in()));
  37. connect(s22,SIGNAL(entered()),this,SLOT(slot_s22_in()));
  38. connect(s3,SIGNAL(entered()),this,SLOT(slot_s3_in()));
  39. connect(s1,SIGNAL(exited()),this,SLOT(slot_s1_out()));
  40. connect(s21,SIGNAL(exited()),this,SLOT(slot_s21_out()));
  41. connect(s22,SIGNAL(exited()),this,SLOT(slot_s22_out()));
  42. connect(s3,SIGNAL(exited()),this,SLOT(slot_s3_out()));
  43. connect(s2,SIGNAL(entered()),this,SLOT(slot_s2_in()));
  44. connect(s2,SIGNAL(exited()),this,SLOT(slot_s2_out()));
  45. //開啟狀態機
  46. machine.start();
  47. }
  48. void Widget::slot_s1_in()
  49. {
  50. qDebug() << "s1 in";
  51. }
  52. void Widget::slot_s1_out()
  53. {
  54. qDebug() << "s1 out";
  55. }
  56. void Widget::slot_s21_in()
  57. {
  58. qDebug() << "s21 in";
  59. }
  60. void Widget::slot_s21_out()
  61. {
  62. qDebug() << "s21 out";
  63. }
  64. void Widget::slot_s22_in()
  65. {
  66. qDebug() << "s22 in";
  67. }
  68. void Widget::slot_s22_out()
  69. {
  70. qDebug() << "s22 out";
  71. }
  72. void Widget::slot_s3_in()
  73. {
  74. qDebug() << "s3 in";
  75. }
  76. void Widget::slot_s3_out()
  77. {
  78. qDebug() << "s3 out";
  79. }
  80. void Widget::slot_s2_in()
  81. {
  82. qDebug() << "s2 in";
  83. }
  84. void Widget::slot_s2_out()
  85. {
  86. qDebug() << "s2 out";
  87. }
  88. Widget::~Widget()
  89. {
  90. delete ui;
  91. }
說明:

測試發現,進子狀態,首先先進父狀態,跳轉到其他狀態,則會先退出當前子狀態,然後再退出父狀態.

Copyright © Linux教程網 All Rights Reserved