一、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 中定义好了的