Qt利用QState狀態(tài)機(jī)實(shí)現(xiàn)控件互斥操作詳解
最近學(xué)習(xí)了QState狀態(tài)機(jī)功能,今天為大家分享下如何實(shí)現(xiàn)按鈕的互斥效果吧。
首先,看一下實(shí)現(xiàn)效果~

功能講解
開(kāi)發(fā)環(huán)境:VS2017 + Qt5.14.2
該例子實(shí)現(xiàn)了類(lèi)似于QRadioButton的效果。
從QtDesigner中拖出了三個(gè)QPushButton控件,分別是:ui.btn1、ui.btn2、ui.btn3,每個(gè)按鈕都有對(duì)應(yīng)的狀態(tài),分別是:state1、state2、state3
選中后背景顏色值是:QColor(255,182,193)、未選中的背景顏色值是:QColor(255,239,213);
設(shè)置步驟
1:設(shè)置btn1對(duì)應(yīng)的狀態(tài)信息
QState *state1 = new QState;
state1->assignProperty(ui.btn1, "text", QStringLiteral("1選中"));
state1->assignProperty(ui.btn1, "styleSheet", "background-color:rgb(255,182,193)");
state1->assignProperty(ui.btn2, "text", QStringLiteral("2"));
state1->assignProperty(ui.btn2, "styleSheet", "background-color:rgb(255,239,213)");
state1->assignProperty(ui.btn3, "text", QStringLiteral("3"));
state1->assignProperty(ui.btn3, "styleSheet", "background-color:rgb(255,239,213)");
代碼講解使用QState::assignProperty,指示此狀態(tài)在進(jìn)入狀態(tài)時(shí)將具有給定對(duì)象的給定名稱(chēng)的屬性設(shè)置為給定值。
通俗來(lái)說(shuō),就是響應(yīng)狀態(tài)需要讓哪些按鈕做什么樣的操作。
在響應(yīng)state1狀態(tài)時(shí),btn1的文字變成了"1選中",背景顏色也發(fā)生了變化,同理,state2、state3也是如此。
2:設(shè)置btn2對(duì)應(yīng)的狀態(tài)信息
QState *state2 = new QState;
state2->assignProperty(ui.btn1, "text", QStringLiteral("1"));
state2->assignProperty(ui.btn1, "styleSheet", "background-color:rgb(255,239,213)");
state2->assignProperty(ui.btn2, "text", QStringLiteral("2選中"));
state2->assignProperty(ui.btn2, "styleSheet", "background-color:rgb(255,182,193)");
state2->assignProperty(ui.btn3, "text", QStringLiteral("3"));
state2->assignProperty(ui.btn3, "styleSheet", "background-color:rgb(255,239,213)");
3:設(shè)置btn3對(duì)應(yīng)的狀態(tài)信息
QState *state3 = new QState;
state3->assignProperty(ui.btn1, "text", QStringLiteral("1"));
state3->assignProperty(ui.btn1, "styleSheet", "background-color:rgb(255,239,213)");
state3->assignProperty(ui.btn2, "text", QStringLiteral("2"));
state3->assignProperty(ui.btn2, "styleSheet", "background-color:rgb(255,239,213)");
state3->assignProperty(ui.btn3, "text", QStringLiteral("3選中"));
state3->assignProperty(ui.btn3, "styleSheet", "background-color:rgb(255,182,193)");
4:設(shè)置停止?fàn)顟B(tài)
當(dāng)設(shè)置了所有控件對(duì)應(yīng)的狀態(tài)后,最后需要設(shè)置停止?fàn)顟B(tài)。停止?fàn)顟B(tài)是一個(gè)單獨(dú)的狀態(tài)類(lèi):QFinalState。
QFinalState *stateFinal = new QFinalState;
5:數(shù)據(jù)綁定
每個(gè)單獨(dú)的狀態(tài)設(shè)置完成后,那么該如何對(duì)狀態(tài)以及按鈕做綁定呢?
state1->addTransition(ui.btn1, &QPushButton::clicked, state1); state2->addTransition(ui.btn2, &QPushButton::clicked, state2); state3->addTransition(ui.btn3, &QPushButton::clicked, state3);
6:將所有的狀態(tài)添加到狀態(tài)機(jī)QStateMachine中
QStateMachine *pMachine = new QStateMachine; pMachine->addState(state1); pMachine->addState(state2); pMachine->addState(state3); pMachine->addState(stateFinal);
7:設(shè)置初始化狀態(tài)
上述工作完成后,必須要給狀態(tài)機(jī)設(shè)置初始狀態(tài),并且狀態(tài)必須是這個(gè)狀態(tài)的子狀態(tài)。
pMachine->setInitialState(state1);
8:開(kāi)始運(yùn)行狀態(tài)
pMachine->start();
好了,根據(jù)上述代碼,進(jìn)行調(diào)試運(yùn)行試試?
結(jié)果發(fā)現(xiàn),無(wú)論點(diǎn)擊哪個(gè)按鈕,按鈕都沒(méi)有反應(yīng),原因出到哪里呢?
答:錯(cuò)誤是出在了第5步,當(dāng)前狀態(tài)是無(wú)法綁定自己的,那么該如何實(shí)現(xiàn)這種互斥?
對(duì)需要進(jìn)行控件綁定的狀態(tài):stat1、state2、state3,設(shè)置一個(gè)父狀態(tài),由父狀態(tài)來(lái)分配數(shù)據(jù)綁定就可以實(shí)現(xiàn)啦。
修改方案
1:創(chuàng)建父狀態(tài)
QState *stateParent = new QState;
2:每個(gè)狀態(tài)設(shè)置父狀態(tài)
對(duì)state1、state2、state3的構(gòu)造函數(shù)中,分別繼承自stateParent,修改如下:
QState *state1 = new QState(stateParent); QState *state2 = new QState(stateParent); QState *state3 = new QState(stateParent);
3:數(shù)據(jù)綁定修改
由父狀態(tài)進(jìn)行分配狀態(tài)對(duì)應(yīng),修改如下:
stateParent->addTransition(ui.btn1, &QPushButton::clicked, state1); stateParent->addTransition(ui.btn2, &QPushButton::clicked, state2); stateParent->addTransition(ui.btn3, &QPushButton::clicked, state3); QFinalState *stateFinal = new QFinalState(stateParent);
并且,初始化父狀態(tài)的初始子狀態(tài)
stateParent->setInitialState(state1);
4:狀態(tài)機(jī)數(shù)據(jù)綁定
此時(shí),不需要將state1、state2、state3直接綁定到pMachine中了,而是將stateParent綁定到pMachine中。
并且,設(shè)置狀態(tài)機(jī)pMachine的初始狀態(tài)是stateParent。
經(jīng)過(guò)如此修改后,調(diào)試代碼發(fā)現(xiàn),可以實(shí)現(xiàn)按鈕的互斥效果了,也就是文章開(kāi)始的動(dòng)畫(huà)效果。
在不使用狀態(tài)時(shí),使用stateFinal進(jìn)行銷(xiāo)毀就可以了。比如在響應(yīng)關(guān)閉按鈕時(shí),可以做結(jié)束處理
stateParent->addTransition(ui.btnExit, &QPushButton::clicked, stateFinal);
下面貼出完整代碼

今日份分享就到這里了~
到此這篇關(guān)于Qt利用QState狀態(tài)機(jī)實(shí)現(xiàn)控件互斥操作詳解的文章就介紹到這了,更多相關(guān)Qt控件互斥操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
給C語(yǔ)言初學(xué)者的學(xué)習(xí)建議
在本篇文章里小編給大家分享的是關(guān)于C語(yǔ)言學(xué)習(xí)建議的相關(guān)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。2020-06-06
C++ Opencv自寫(xiě)函數(shù)實(shí)現(xiàn)膨脹腐蝕處理技巧
這篇文章主要介紹了C++ Opencv 自寫(xiě)函數(shù)實(shí)現(xiàn)膨脹腐蝕處理,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10
Visual Studio Code 2020安裝教程及CPP環(huán)境配置(教程圖解)
這篇文章主要介紹了Visual Studio Code 2020安裝教程、CPP環(huán)境配置,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
仿寫(xiě)C語(yǔ)言string.h頭文件檢驗(yàn)字符串函數(shù)
這里給大家分享的是一個(gè)C語(yǔ)言string.h頭文件檢驗(yàn)字符串函數(shù)的仿寫(xiě),非常的簡(jiǎn)單實(shí)用,小編覺(jué)得這篇文寫(xiě)的還不錯(cuò),希望能夠給你帶來(lái)幫助2021-11-11
solaris操作系統(tǒng)做c應(yīng)用程序開(kāi)發(fā)步驟
solaris操作系統(tǒng)做c應(yīng)用程序開(kāi)發(fā)步驟,大家參考使用吧2013-12-12
基于C++的農(nóng)夫過(guò)河問(wèn)題算法設(shè)計(jì)與實(shí)現(xiàn)方法
這篇文章主要介紹了基于C++的農(nóng)夫過(guò)河問(wèn)題算法設(shè)計(jì)與實(shí)現(xiàn)方法,簡(jiǎn)單描述了農(nóng)夫過(guò)河問(wèn)題,并結(jié)合實(shí)例形式詳細(xì)分析了基于C++實(shí)現(xiàn)農(nóng)夫過(guò)河問(wèn)題的相關(guān)算法實(shí)現(xiàn)步驟與操作技巧,需要的朋友可以參考下2017-09-09

