Qt 范例阅读: QStateMachine状态机框架 和 SCXML 引擎简单记录(方便后续有需求能想到这两个东西)

一、QStateMachine 简单应用: 实现按钮的文本切换

    QStateMachine machine; //定义状态机(头文件定义)

    QState *off = new QState(); //添加off 状态
    off->assignProperty(ui->pushButton_2, "text", "Off"); //绑定该状态到按钮的 text 属性上
    off->setObjectName("off");
    QState *on = new QState(); //添加off 状态
    on->setObjectName("on");
    on->assignProperty(ui->pushButton_2, "text", "On"); //绑定该状态到按钮的 text 属性上
    off->addTransition(ui->pushButton_2, &QAbstractButton::clicked, on); //添加转换条件
    on->addTransition(ui->pushButton_2, &QAbstractButton::clicked, off);

    //绑定状态 进入、退出 信号
    QObject::connect(on, &QState::entered, this, [=](){
        qDebug() << "QState on enter";
    });
    QObject::connect(off, &QState::exited, this, [=](){
        qDebug() << "QState off exited";
    });

    //添加状态到状态机
    machine.addState(off);
    machine.addState(on);
    machine.setInitialState(off); //设置初始状态
    machine.start(); //运行状态机

二、SCXML: 一种 状态机描述 XML 格式文件 ;qt 可以之间通过 图形界面拖拽的方式生成,比较方便。具体案例 qt 搜索 scxml 即可。

案例:交通灯:trafficlight-widgets-dynamic

scxml 文件含义:定义了两个大的状态 working 、broken

working 状态下子状态有:red 、green、yellow(子状态:redGoingGreen、greenGoingRed)

broken 状态下子状态有: blinking 、 unblinking

整个文件已经定义好了各个状态之间的切换条件、所以启动状态机后状态机会自动运转

属性界面:red : 标识状态 ;onentry 标识 进入red 状态要执行的行为 是 send startGoingGreen 事件。下面delay 3s 应该是延时3s 才发送事件

main.cpp

    //读取scxml 文件内容,创建状态机
    QScxmlStateMachine *machine = QScxmlStateMachine::fromFile(
                QStringLiteral(":statemachine.scxml"));
    if (!machine->parseErrors().isEmpty()) {
        QTextStream errs(stderr, QIODevice::WriteOnly);
        const auto errors = machine->parseErrors();
        for (const QScxmlError &error : errors) {
            errs << error.toString();
        }

        return -1;
    }

    TrafficLight widget(machine); //和状态机绑定的界面
    widget.show();
    machine->setParent(&widget);
    machine->start(); //启动状态机

TrafficLight.cpp

    //将状态机的状态 和 界面相关的处理函数链接
    machine->connectToState(QStringLiteral("red"),
                            widget->redLight(), &LightWidget::switchLight);
    machine->connectToState(QStringLiteral("redGoingGreen"),
                            widget->redLight(), &LightWidget::switchLight);
    machine->connectToState(QStringLiteral("yellow"),
                            widget->yellowLight(), &LightWidget::switchLight);
    machine->connectToState(QStringLiteral("blinking"),
                            widget->yellowLight(), &LightWidget::switchLight);
    machine->connectToState(QStringLiteral("green"),
                            widget->greenLight(), &LightWidget::switchLight);

    //状态机的切换逻辑是在scxml 中定义好了的
相关推荐
锦亦之22339 小时前
QT+OSG+OSG-earth如何在窗口显示一个地球
开发语言·qt
柳鲲鹏12 小时前
编译成功!QT/6.7.2/Creator编译Windows64 MySQL驱动(MinGW版)
开发语言·qt·mysql
三玖诶12 小时前
如何在 Qt 的 QListWidget 中逐行添加和显示数据
开发语言·qt
阳光开朗_大男孩儿18 小时前
DBUS属性原理
linux·服务器·前端·数据库·qt
Alphapeople19 小时前
Qt Modbus
开发语言·qt
竹林海中敲代码19 小时前
Qt Creator 集成开发环境 常见问题
qt·qt工具常见问题
竹林海中敲代码1 天前
Qt安卓开发连接手机调试(红米K60为例)
android·qt·智能手机
长沙红胖子Qt1 天前
关于 Qt运行加载内存较大崩溃添加扩大运行内存 的解决方法
开发语言·qt·qt扩大运行内存
gopher95111 天前
qt相关面试题
开发语言·qt·面试
三玖诶1 天前
在 Qt 中使用 QLabel 设置 GIF 动态背景
开发语言·qt·命令模式