Qt Qml狀態機器架構,qtqml狀態架構
Qt5.4引入了QML狀態機器架構,與C++狀態機器架構類似,可以在應用程式中建立並執行狀態圖。為此,QtQml.StateMachine模組提供了一些相關的QML類型,用於建立事件驅動的狀態機器,這些QML類型列舉如下:
StateMachine——狀態機器管家,執行演算法基於SCXML(State Chart XML),在狀態機器啟動之前要設定好初始狀態,即initialState屬性。
State——狀態機器中的通用類型,注意與QtQuick模組中的State類型不同,匯入模組時先匯入QtQuick模組,後匯入QtQml.StateMachine模組。
FinalState——顧名思義,狀態機器工作結束時使用這個狀態,會觸發這個狀態機器的finished()訊號。
HistoryState——是個偽狀態,記錄了最後一次退出父狀態時的子狀態,一開始可指定一個預設狀態。
SignalTransition——根據特定的訊號切換狀態。
TimeoutTransition——根據定時器切換狀態。
下面是一個綜合的例子:
// Qt5.4// 先匯入QtQuick模組,後匯入QtQml.StateMachine模組import QtQuick 2.4import QtQuick.Controls 1.2import QtQml.StateMachine 1.0Item { width: 400 height: 200 Row { anchors.centerIn: parent spacing: 10 Button { id: startButton text: "start" onClicked: { // 啟動狀態機器 if (!stateMachine.running) { stateMachine.running = true } } } Button { id: button // 狀態機器標識 text: s11.active ? "s11" : s12.active ? "s12" : s13.active ? "s13" : "state" } Button { id: historyButton // 曆史狀態記錄 text: stateMachine.running ? s1.active ? "interrupt" : "resume" : "history" } Button { id: quitButton text: "quit" } } StateMachine { id: stateMachine initialState: s1 // 初始狀態 // running: true // running屬性由button(startButton)設定 State { id: s1 initialState: s11 // 初始狀態 SignalTransition { targetState: s3 // 根據signal切換state signal: historyButton.clicked } SignalTransition { targetState: s2 // 根據signal切換state signal: quitButton.clicked } onEntered: console.log("s1 entered") onExited: console.log("s1 exited") State { id: s11 SignalTransition { targetState: s12 // 根據signal切換state signal: button.clicked } onEntered: console.log("s11 entered") onExited: console.log("s11 exited") } State { id: s12 SignalTransition { // 根據signal切換state targetState: s13 signal: button.clicked } SignalTransition { // override父state的signal(quitButton.clicked) signal: quitButton.clicked onTriggered: console.log("override - quitButton clicked") } onEntered: console.log("s12 entered") onExited: console.log("s12 exited") } State { id: s13 SignalTransition { // 根據signal切換state targetState: s11 signal: button.clicked } TimeoutTransition { // 根據定時器切換state targetState: s2 timeout: 2000 } onEntered: console.log("s13 entered") onExited: console.log("s13 exited") } HistoryState { // 曆史狀態 id: history } } State { id: s3 SignalTransition { // 根據signal切換state targetState: history signal: historyButton.clicked } onEntered: console.log("s3 entered") onExited: console.log("s3 exited") } FinalState { id: s2 } onFinished: console.log("state finished") }}
另外,State的childMode屬性預設是單狀態模式,一開始要設定一個初始狀態,我們還可以設定childMode為並行模式,當進入父狀態時,就會同時進入所有的子狀態。
詳細介紹可參考如下Qt官網文檔:
http://doc.qt.io/qt-5/qmlstatemachine.html