Qt利用QState狀態(tài)機(jī)實(shí)現(xiàn)控件互斥操作詳解
最近學(xué)習(xí)了QState狀態(tài)機(jī)功能,今天為大家分享下如何實(shí)現(xiàn)按鈕的互斥效果吧。
首先,看一下實(shí)現(xiàn)效果~
功能講解
開發(fā)環(huán)境:VS2017 + Qt5.14.2
該例子實(shí)現(xiàn)了類似于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ì)象的給定名稱的屬性設(shè)置為給定值。
通俗來說,就是響應(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)類: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:開始運(yùn)行狀態(tài)
pMachine->start();
好了,根據(jù)上述代碼,進(jìn)行調(diào)試運(yùn)行試試?
結(jié)果發(fā)現(xiàn),無論點(diǎn)擊哪個(gè)按鈕,按鈕都沒有反應(yīng),原因出到哪里呢?
答:錯(cuò)誤是出在了第5步,當(dāng)前狀態(tài)是無法綁定自己的,那么該如何實(shí)現(xiàn)這種互斥?
對(duì)需要進(jìn)行控件綁定的狀態(tài):stat1、state2、state3,設(shè)置一個(gè)父狀態(tài),由父狀態(tà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)過如此修改后,調(diào)試代碼發(fā)現(xiàn),可以實(shí)現(xiàn)按鈕的互斥效果了,也就是文章開始的動(dòng)畫效果。
在不使用狀態(tài)時(shí),使用stateFinal進(jìn)行銷毀就可以了。比如在響應(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)文章
VC MFC非模態(tài)對(duì)話框的實(shí)現(xiàn)方法
這篇文章主要介紹了VC MFC非模態(tài)對(duì)話框的實(shí)現(xiàn)方法,有助于讀者加深對(duì)于模態(tài)對(duì)話框與非模態(tài)對(duì)話框的理解與運(yùn)用,需要的朋友可以參考下2014-07-07C語言中進(jìn)行函數(shù)指針回調(diào)的實(shí)現(xiàn)步驟
在 C 語言中,函數(shù)指針的回調(diào)是一種強(qiáng)大的編程技術(shù),它允許我們?cè)谔囟ǖ氖录l(fā)生或特定的條件滿足時(shí),調(diào)用由用戶定義的函數(shù),這種機(jī)制增加了程序的靈活性和可擴(kuò)展性,使得代碼更具通用性和可重用性,本文給大家介紹了C語言中進(jìn)行函數(shù)指針回調(diào)的實(shí)現(xiàn)步驟,需要的朋友可以參考下2024-07-07c語言統(tǒng)計(jì)素?cái)?shù)之和的實(shí)例
這篇文章主要介紹了c語言統(tǒng)計(jì)素?cái)?shù)之和的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12基礎(chǔ)C語言編程時(shí)易犯錯(cuò)誤有哪些
基礎(chǔ)C語言編程時(shí)易犯錯(cuò)誤有哪些?這篇文章主要介紹了C語言編程時(shí)常見的錯(cuò)誤,感興趣的小伙伴們可以參考一下2016-11-11