【QT】Qt Qml状态机框架

Qt5.4引入了QML状态机框架,与C++状态机框架类似,可以在应用程序中创建并执行状态图。为此,QtQml.StateMachine模块提供了一些相关的QML类型,用于创建事件驱动的状态机,这些QML类型列举如下:

StateMachine——状态机管家,执行算法基于SCXMLState Chart XML),在状态机启动之前要设置好初始状态,即initialState属性。

State——状态机中的通用类型,注意与QtQuick模块中的State类型不同,导入模块时先导入QtQuick模块,后导入QtQml.StateMachine模块。

FinalState——顾名思义,状态机工作结束时使用这个状态,会触发这个状态机的finished()信号。

HistoryState——是个伪状态,记录了最后一次退出父状态时的子状态,一开始可指定一个默认状态。

SignalTransition——根据特定的信号切换状态。

TimeoutTransition——根据定时器切换状态。


下面是一个综合的例子:

// Qt5.4
// 先导入QtQuick模块,后导入QtQml.StateMachine模块
import QtQuick 2.4
import QtQuick.Controls 1.2
import QtQml.StateMachine 1.0

Item {
    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")
    }
}


另外,StatechildMode属性默认是单状态模式,一开始要设置一个初始状态,我们还可以设置childMode为并行模式,当进入父状态时,就会同时进入所有的子状态。

详细介绍可参考如下Qt官网文档:

http://doc.qt.io/qt-5/qmlstatemachine.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值