最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt中狀態(tài)機框架QState的實現(xiàn)

 更新時間:2025年11月11日 10:52:49   作者:MzKyle  
這篇文章主要介紹了Qt中狀態(tài)機框架QState的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

QState是Qt狀態(tài)機框架(Qt State Machine Framework)的核心類,用于建模離散狀態(tài)以及狀態(tài)間的轉(zhuǎn)換邏輯,廣泛應用于UI交互流程、設(shè)備狀態(tài)管理、工作流控制等場景。它基于UML狀態(tài)圖規(guī)范設(shè)計,支持層次化狀態(tài)、并行狀態(tài)、歷史狀態(tài)等高級特性,能夠簡化復雜狀態(tài)邏輯的實現(xiàn)。

一、核心定位與繼承關(guān)系

QState繼承自QAbstractState(抽象狀態(tài)基類),而QAbstractState又繼承自QObject,因此QState具備Qt對象模型的所有特性(如信號槽、元對象系統(tǒng)、父子關(guān)系管理)。其核心作用是:

  • 封裝一個離散狀態(tài)的l行為(進入/退出時的動作);
  • 管理狀態(tài)間的轉(zhuǎn)換規(guī)則(QAbstractTransition);
  • 支持子狀態(tài)嵌套,構(gòu)建層次化狀態(tài)機;
  • QStateMachine配合,實現(xiàn)狀態(tài)的自動切換。

狀態(tài)機的基本構(gòu)成包括:

  • 狀態(tài)(State):如QState、QParallelState(并行狀態(tài))、QHistoryState(歷史狀態(tài));
  • 轉(zhuǎn)換(Transition):如QSignalTransition(信號觸發(fā))、QEventTransition(事件觸發(fā));
  • 事件(Event):觸發(fā)狀態(tài)轉(zhuǎn)換的信號、Qt事件或自定義事件;
  • 狀態(tài)機(State Machine)QStateMachine,負責調(diào)度狀態(tài)切換與事件處理。

二、基礎(chǔ)用法:狀態(tài)創(chuàng)建與轉(zhuǎn)換

1. 狀態(tài)的創(chuàng)建與添加

通過QStateMachine管理狀態(tài),需先創(chuàng)建狀態(tài)實例并添加到狀態(tài)機中:

#include <QStateMachine>
#include <QState>
#include <QPushButton>

QStateMachine *machine = new QStateMachine;

// 創(chuàng)建狀態(tài)
QState *s1 = new QState(machine);  // 直接指定父對象為狀態(tài)機
QState *s2 = new QState;
machine->addState(s2);  // 或通過addState()添加

// 設(shè)置初始狀態(tài)(狀態(tài)機啟動時進入的第一個狀態(tài))
machine->setInitialState(s1);

2. 狀態(tài)轉(zhuǎn)換的定義

狀態(tài)轉(zhuǎn)換(QAbstractTransition)是狀態(tài)切換的規(guī)則,需指定“觸發(fā)條件”和“目標狀態(tài)”。QState通過addTransition()方法添加轉(zhuǎn)換,常用轉(zhuǎn)換類型包括:

(1)信號觸發(fā)轉(zhuǎn)換(QSignalTransition)

最常用的轉(zhuǎn)換類型,當特定信號發(fā)射時觸發(fā)狀態(tài)切換:

QPushButton *btn = new QPushButton("Next");

// 當btn發(fā)射clicked()信號時,從s1轉(zhuǎn)換到s2
s1->addTransition(btn, &QPushButton::clicked, s2);

// 進階:轉(zhuǎn)換可攜帶動作(通過onTransition()信號)
QSignalTransition *trans = s1->addTransition(btn, &QPushButton::clicked, s2);
connect(trans, &QSignalTransition::onTransition, [](){
    qDebug() << "從s1切換到s2";  // 轉(zhuǎn)換過程中執(zhí)行的動作
});

(2)事件觸發(fā)轉(zhuǎn)換(QEventTransition)

基于Qt事件(如QKeyEventQMouseEvent)觸發(fā)轉(zhuǎn)換:

#include <QEventTransition>

// 當s1收到QEvent::KeyPress事件時,轉(zhuǎn)換到s2
QEventTransition *keyTrans = new QEventTransition(btn, QEvent::KeyPress);
keyTrans->setTargetState(s2);
s1->addTransition(keyTrans);

(3)守衛(wèi)條件(Guard)

轉(zhuǎn)換可設(shè)置守衛(wèi)條件(布爾函數(shù)),僅當條件為true時才執(zhí)行轉(zhuǎn)換:

// 定義守衛(wèi)函數(shù)(返回bool)
bool canTransition() {
    return someCondition;  // 例如:檢查輸入是否合法
}

// 為轉(zhuǎn)換設(shè)置守衛(wèi)
trans->setGuard(canTransition);  // 僅當canTransition()為true時,轉(zhuǎn)換才生效

三、狀態(tài)行為:進入與退出動作

QState在進入(entered)和退出(exited)時會發(fā)射對應信號,可通過信號槽機制綁定狀態(tài)切換時的動作。此外,還可通過onEntry()onExit()方法直接設(shè)置動作函數(shù)。

1. 信號綁定方式

// 進入s1時執(zhí)行動作
connect(s1, &QState::entered, [](){
    qDebug() << "進入狀態(tài)s1";
    // 例如:更新UI顯示、啟動定時器
});

// 退出s1時執(zhí)行動作
connect(s1, &QState::exited, [](){
    qDebug() << "退出狀態(tài)s1";
    // 例如:停止定時器、保存臨時數(shù)據(jù)
});

2. 動作函數(shù)方式

通過assignProperty()可在進入狀態(tài)時自動為對象設(shè)置屬性,簡化UI狀態(tài)管理:

QPushButton *btn = new QPushButton("Click me");

// 進入s1時,將btn的text屬性設(shè)為"狀態(tài)1",enabled設(shè)為true
s1->assignProperty(btn, "text", "狀態(tài)1");
s1->assignProperty(btn, "enabled", true);

// 進入s2時,更新btn屬性
s2->assignProperty(btn, "text", "狀態(tài)2");
s2->assignProperty(btn, "enabled", false);

當狀態(tài)激活時,assignProperty()設(shè)置的屬性會自動應用到目標對象,退出狀態(tài)時不會自動恢復(需手動在exited信號中處理)。

四、層次化狀態(tài):父狀態(tài)與子狀態(tài)

QState支持嵌套子狀態(tài),形成層次化結(jié)構(gòu)(父狀態(tài)包含子狀態(tài)),這是實現(xiàn)復雜狀態(tài)邏輯的核心特性。

1. 子狀態(tài)的添加與初始子狀態(tài)

// 創(chuàng)建父狀態(tài)
QState *parentState = new QState;

// 創(chuàng)建子狀態(tài)(指定父狀態(tài))
QState *child1 = new QState(parentState);
QState *child2 = new QState(parentState);

// 設(shè)置父狀態(tài)的初始子狀態(tài)(進入父狀態(tài)時自動進入該子狀態(tài))
parentState->setInitialState(child1);

2. 層次化狀態(tài)的行為規(guī)則

  • 進入父狀態(tài):先執(zhí)行父狀態(tài)的entered動作,再進入其初始子狀態(tài)(執(zhí)行子狀態(tài)的entered動作);
  • 退出父狀態(tài):先退出當前活躍的子狀態(tài)(執(zhí)行子狀態(tài)的exited動作),再執(zhí)行父狀態(tài)的exited動作;
  • 子狀態(tài)轉(zhuǎn)換限制:子狀態(tài)的轉(zhuǎn)換默認只能在同一父狀態(tài)的子狀態(tài)間進行,若需轉(zhuǎn)換到外部狀態(tài),需顯式指定目標。

示例:播放器的“播放中”狀態(tài)(父狀態(tài))包含“正常播放”和“快進”子狀態(tài):

QState *playing = new QState;  // 父狀態(tài):播放中
QState *normalPlay = new QState(playing);  // 子狀態(tài):正常播放
QState *fastForward = new QState(playing); // 子狀態(tài):快進

playing->setInitialState(normalPlay);

// 子狀態(tài)間轉(zhuǎn)換:正常播放 → 快進(按快進鍵)
normalPlay->addTransition(fastForwardBtn, &QPushButton::clicked, fastForward);
// 子狀態(tài)轉(zhuǎn)換到外部狀態(tài):任何子狀態(tài)下按停止鍵 → 停止狀態(tài)
playing->addTransition(stopBtn, &QPushButton::clicked, stopped);

五、特殊狀態(tài)類型

1. 并行狀態(tài)(QParallelState)

用于建模同時活躍的多個狀態(tài)(如設(shè)備同時處于“聯(lián)網(wǎng)”和“充電”狀態(tài))。QParallelStateQState的子類,其所有子狀態(tài)會同時進入和退出。

#include <QParallelState>

QParallelState *parallel = new QParallelState;

// 兩個并行子狀態(tài)
QState *networkState = new QState(parallel);  // 網(wǎng)絡狀態(tài)
QState *powerState = new QState(parallel);    // 電源狀態(tài)

// 進入parallel時,networkState和powerState同時激活
machine->setInitialState(parallel);

并行狀態(tài)的退出規(guī)則:所有子狀態(tài)退出后,并行狀態(tài)才會退出。

2. 歷史狀態(tài)(QHistoryState)

用于保存父狀態(tài)中最后活躍的子狀態(tài),當父狀態(tài)再次進入時,自動恢復到該子狀態(tài)(避免重復初始化)。分為兩種類型:

  • 淺歷史(默認):僅恢復直接子狀態(tài)的歷史;
  • 深歷史:遞歸恢復所有嵌套子狀態(tài)的歷史(通過setDeepHistory(true)啟用)。
#include <QHistoryState>

QState *parent = new QState;
QState *child1 = new QState(parent);
QState *child2 = new QState(parent);
parent->setInitialState(child1);

// 創(chuàng)建歷史狀態(tài)(作為parent的子狀態(tài))
QHistoryState *history = new QHistoryState(parent);
// 啟用深歷史(可選)
history->setDeepHistory(true);

// 從外部狀態(tài)轉(zhuǎn)換到history時,恢復parent的最后活躍子狀態(tài)
externalState->addTransition(backBtn, &QPushButton::clicked, history);

六、狀態(tài)機的運行與生命周期

1. 狀態(tài)機的啟動與停止

// 啟動狀態(tài)機(開始處理事件并進入初始狀態(tài))
machine->start();

// 停止狀態(tài)機(退出當前狀態(tài),暫停事件處理)
machine->stop();

狀態(tài)機啟動后,會觸發(fā)初始狀態(tài)的entered信號,并開始監(jiān)聽事件以驅(qū)動轉(zhuǎn)換。

2. 狀態(tài)機的完成與終止

當狀態(tài)機進入“終止狀態(tài)”(QFinalState)時,會發(fā)射finished()信號并停止運行:

#include <QFinalState>

QFinalState *final = new QFinalState(machine);

// 從s2轉(zhuǎn)換到終止狀態(tài)
s2->addTransition(quitBtn, &QPushButton::clicked, final);

// 狀態(tài)機完成時退出程序
connect(machine, &QStateMachine::finished, qApp, &QApplication::quit);

七、高級特性與底層機制

1. 事件優(yōu)先級與處理順序

狀態(tài)機的事件處理遵循以下規(guī)則:

  • 子狀態(tài)的事件處理器優(yōu)先于父狀態(tài);
  • 同一狀態(tài)的多個轉(zhuǎn)換按添加順序檢查(守衛(wèi)條件先滿足者觸發(fā));
  • 并行狀態(tài)的子狀態(tài)獨立處理事件,互不干擾。

2. 自定義轉(zhuǎn)換與事件

通過繼承QAbstractTransition可實現(xiàn)自定義轉(zhuǎn)換邏輯,通過QEvent子類可定義自定義事件:

// 自定義事件
class MyEvent : public QEvent {
public:
    static const QEvent::Type Type = static_cast<QEvent::Type>(QEvent::User + 1);
    MyEvent() : QEvent(Type) {}
};

// 自定義轉(zhuǎn)換(監(jiān)聽MyEvent)
class MyTransition : public QAbstractTransition {
protected:
    bool eventTest(QEvent *e) override {
        return e->type() == MyEvent::Type;  // 僅響應MyEvent
    }
    void onTransition(QEvent *) override {
        // 轉(zhuǎn)換動作
    }
};

// 使用自定義轉(zhuǎn)換
MyTransition *trans = new MyTransition;
trans->setTargetState(s2);
s1->addTransition(trans);

3. 調(diào)試與狀態(tài)監(jiān)控

Qt提供QStateMachine::setDebuggingEnabled(true)開啟調(diào)試日志,輸出狀態(tài)轉(zhuǎn)換過程:

machine->setDebuggingEnabled(true);  // 控制臺會打印狀態(tài)切換日志

也可通過QState::active()方法實時檢查狀態(tài)是否活躍:

if (s1->active()) {
    qDebug() << "當前處于s1狀態(tài)";
}

八、常見問題

  1. 狀態(tài)轉(zhuǎn)換循環(huán):避免無守衛(wèi)條件的循環(huán)轉(zhuǎn)換(如s1→s2→s1),可能導致狀態(tài)機無限切換;
  2. 子狀態(tài)與父狀態(tài)的信號沖突:子狀態(tài)的entered信號會在父狀態(tài)之后觸發(fā),需注意動作執(zhí)行順序;
  3. 并行狀態(tài)的同步:并行子狀態(tài)的轉(zhuǎn)換獨立,若需同步退出,可統(tǒng)一轉(zhuǎn)換到同一個終止狀態(tài);
  4. 歷史狀態(tài)的濫用:僅在需要恢復狀態(tài)時使用,過度使用會增加狀態(tài)機復雜度;
  5. 性能考量:復雜狀態(tài)機(>100個狀態(tài))需避免頻繁轉(zhuǎn)換,可通過合并狀態(tài)減少開銷。

QState作為Qt狀態(tài)機框架的核心,通過封裝狀態(tài)行為、轉(zhuǎn)換規(guī)則和層次化結(jié)構(gòu),大幅簡化了復雜狀態(tài)邏輯的實現(xiàn)。其特性包括:支持信號/事件觸發(fā)的轉(zhuǎn)換、狀態(tài)進入/退出動作、屬性自動賦值、層次化與并行狀態(tài)、歷史狀態(tài)恢復等。

到此這篇關(guān)于Qt中狀態(tài)機框架QState的實現(xiàn)的文章就介紹到這了,更多相關(guān)Qt 狀態(tài)機框架QState內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言實現(xiàn)三子棋游戲附注釋

    C語言實現(xiàn)三子棋游戲附注釋

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)三子棋游戲附注釋,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C++的幾種編譯器的實現(xiàn)

    C++的幾種編譯器的實現(xiàn)

    本文主要介紹了C++的幾種編譯器的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2026-03-03
  • 使用VScode搭建ROS開發(fā)環(huán)境的教程詳解

    使用VScode搭建ROS開發(fā)環(huán)境的教程詳解

    這篇文章主要介紹了使用VScode搭建ROS開發(fā)環(huán)境,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • matlab遺傳算法求解車間調(diào)度問題分析及實現(xiàn)源碼

    matlab遺傳算法求解車間調(diào)度問題分析及實現(xiàn)源碼

    這篇文章主要為大家介紹了matlab遺傳算法求解車間調(diào)度問題解析,文中附含詳細實現(xiàn)源碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-02-02
  • OpenGL通過中點法繪制直線和圓

    OpenGL通過中點法繪制直線和圓

    這篇文章主要為大家詳細介紹了OpenGL通過中點法繪制直線和圓,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C++實現(xiàn)學生宿舍管理系統(tǒng)

    C++實現(xiàn)學生宿舍管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)學生宿舍管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語言中g(shù)etchar()與putchar()函數(shù)詳解

    C語言中g(shù)etchar()與putchar()函數(shù)詳解

    本文主要介紹了C語言中g(shù)etchar()與putchar()函數(shù)詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-01-01
  • C語言例題講解指針與數(shù)組

    C語言例題講解指針與數(shù)組

    在C語言和C++等語言中,數(shù)組元素全為指針變量的數(shù)組稱為指針數(shù)組,指針數(shù)組中的元素都必須具有相同的存儲類型、指向相同數(shù)據(jù)類型的指針變量。指針數(shù)組比較適合用來指向若干個字符串,使字符串處理更加方便、靈活
    2022-07-07
  • C++實現(xiàn)旋轉(zhuǎn)數(shù)組的二分查找

    C++實現(xiàn)旋轉(zhuǎn)數(shù)組的二分查找

    這篇文章主要介紹了C++實現(xiàn)旋轉(zhuǎn)數(shù)組的二分查找方法,涉及數(shù)組的操作,有值得借鑒的技巧,需要的朋友可以參考下
    2014-09-09
  • c++11 新特性——智能指針使用詳解

    c++11 新特性——智能指針使用詳解

    這篇文章主要介紹了c++11 新特性——智能指針使用的相關(guān)資料,幫助大家更好的理解和使用c++,感興趣的朋友可以了解下
    2021-02-02

最新評論

关岭| 若尔盖县| 惠安县| 包头市| 达尔| 阿坝县| 兖州市| 广平县| 德惠市| 卢氏县| 宣恩县| 四川省| 米脂县| 报价| 延庆县| 白城市| 科技| 庆阳市| 腾冲县| 长阳| 前郭尔| 阳新县| 安陆市| 隆尧县| 米林县| 汉沽区| 南江县| 黑河市| 蒙山县| 抚顺市| 涟源市| 千阳县| 宁阳县| 龙口市| 衡水市| 吉安市| 大关县| 亚东县| 庐江县| 杭州市| 比如县|