Qt狀態機器學習2

來源:互聯網
上載者:User

                    我們在使用狀態機器時,可能在執行一組狀態的過程中跳轉到一個新狀態執行完任務後還需要跳轉到原來執行被打斷的地方,Qt的狀態機器架構為我們提供了QHistoryState類。這個類只要將它加入到這組狀態中,它就會記住當然執行到的這組狀態中的哪一個。

                    

#include <QApplication>#include <QState>#include <QStateMachine>#include <QPushButton>#include <QVariant>#include <QFinalState>#include <QLayout>#include <QHistoryState>#include <QLabel>#include <QMessageBox>#include <QtDebug>#include <QAbstractTransition>//Qt的狀態機器是層次的,是事件驅動的,使用到了事件迴圈,那麼就是非同步int main(int argc, char* argv[]){    QApplication app(argc,argv);    QStateMachine sMachine;//一個狀態機器對象    QState s;//和fState在同一個層次    QState s1;//3個狀態物件    s1.setParent(&s);    QState s2;    s2.setParent(&s);    QState s3;    s3.setParent(&s);    s.setInitialState(&s1);//一組狀態中要指定一組狀態中的初始狀態    QHistoryState sh;//記錄s組狀態被打斷的狀態    sh.setParent(&s);    QFinalState fState;    QState is;//中斷狀態    QWidget w;    QHBoxLayout layout;    QPushButton button;    QPushButton qButton;    qButton.setText(QObject::tr("退出"));    QPushButton iButton;    iButton.setText(QObject::tr("打斷"));    QLabel showLabel(QObject::tr("sssssss"));    layout.addWidget(&button);    layout.addWidget(&qButton);    layout.addWidget(&iButton);    layout.addWidget(&showLabel);    w.setLayout(&layout);    QMessageBox box(&w);    box.addButton(QMessageBox::Ok);    box.setText(QObject::tr("打斷了,現在是is"));    box.setIcon(QMessageBox::Information);    s1.addTransition(&button,SIGNAL(clicked()),&s2);//s1為這個過渡的始狀態,s2為末狀態    s2.addTransition(&button,SIGNAL(clicked()),&s3);    s3.addTransition(&button,SIGNAL(clicked()),&s1);    //每個狀態進入時,設定指定對象指定項指定的值    s1.assignProperty(&button,"text","s1");    s2.assignProperty(&button,"text","s2");    s3.assignProperty(&button,"text","s3");    //給每個狀態添加過渡    s.addTransition(&qButton,SIGNAL(clicked()),&fState);//s -- > finalState,但是在這組內的狀態對於這個過渡可以覆蓋    //s2.addTransition(&qButton,SIGNAL(clicked()),&s3);//如果添加這一個句,那麼在s2點擊qButton按鈕    //就不會退出,只是轉向了s3    s.addTransition(&iButton,SIGNAL(clicked()),&is);    is.addTransition(&sh);    QObject::connect(&is,SIGNAL(entered()),&box,SLOT(exec()));    //也可能重寫 QAbstractState::onEntry()和QAbstractState::onExit()函數    //在UML的狀態圖中,每個狀態在進入狀態和離開狀態的時候都會進行相關的操作    //這個可以通過這兩個訊號來解決,也可通過繼承來重寫上述的兩個函數    QObject::connect(&s3,SIGNAL(entered()),&w,SLOT(showMinimized()));    QObject::connect(&s3,SIGNAL(exited()),&w,SLOT(showMaximized()));    QObject::connect(&sMachine,SIGNAL(finished()),&app,SLOT(quit()));    sMachine.addState(&s);//對於狀態機器只是添加頂層的狀態    // sMachine.addState(&s1);    // sMachine.addState(&s2);    // sMachine.addState(&s3);    sMachine.addState(&fState);    sMachine.addState(&is);    //設定狀態機器的初始狀態    //sMachine.setInitialState(&s1);    sMachine.setInitialState(&s);//對於狀態機器的初始化,只是使用頂層的狀態初始化,所以每個頂層如果是    //一組狀態,那麼就要指定這組狀態的初始化狀態    w.show();    //狀態機器開啟    sMachine.start();    //可以通過給狀態分組來實現狀態過渡的共用,比如我們希望在任何狀態下我們都能夠退出,    //那麼這個退出狀態就是比其他的狀態具有高的狀態層次,那麼我們就要將其他的狀態封裝在    //合適的與退出狀態同層次的一個高階的狀態層次中    return app.exec();}

上面的這個例子,在s狀態組中添加了一個QHistoryState對象記錄當前的執行到的狀態。在我們點擊中斷按鈕後,我們從一個s的子狀態跳轉到is狀態,然後在跳轉到s被打斷的狀態。

如所示:

此時我們點擊s2會跳轉到s3,進入s3會觸發

 QObject::connect(&s3,SIGNAL(entered()),&w,SLOT(showMinimized()));

這個訊號和槽,表單會最小化

現在在點擊打斷按鈕,從s3跳轉到is狀態會觸發

    QObject::connect(&s3,SIGNAL(exited()),&w,SLOT(showMaximized()));

所以會最大化,然後彈出一個阻塞的QMessagebox,當我們點擊ok,is會轉到記錄的那個轉出狀態也就是s3,又觸發了

 QObject::connect(&s3,SIGNAL(entered()),&w,SLOT(showMinimized()));

所以會最小化。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.