开发者

Qt利用QState状态机实现控件互斥操作详解

开发者 https://www.devze.com 2022-12-06 10:51 出处:网络 作者: 中国好公民st
目录功能讲解设置步骤1:设置btn1对应的状态信息2:设置btn2对应的状态信息3:设置btn3对应的状态信息4:设置停止状态5:数据绑定6:将所有的状态添加到状态机QStateMAChine中7:设置初始化状态8:开始运行状态修改方
目录
  • 功能讲解
  • 设置步骤
    • 1:设置btn1对应的状态信息
    • 2:设置btn2对应的状态信息
    • 3:设置btn3对应的状态信息
    • 4:设置停止状态
    • 5:数据绑定
    • 6:将所有的状态添加到状态机QStateMAChine中
    • 7:设置初始化状态
    • 8:开始运行状态
  • 修改方案
    • 1:创建父状态
    • 2:每个状态设置父状态
    • 3:数据绑定修改
    • 4:状态机数据绑定

最近学习了QState状态机功能,今天为大家分享下如何实现按钮的互斥效果吧。

首先,看一下实现效果~

Qt利用QState状态机实现控件互斥操作详解

功能讲解

开发环境:VS2017 + Qt5.14.2

该例子实现了类似于QRadioButton的效果。

从QtDesigner中拖出了三个QPushButton控件,分别是:ui.btn1、ui.btn2、ui.btn3,每个按钮都有对应的状态,分别是:state1、state2、state3

选中后背景颜色值是:QColor(255,182,193)、未选中的背景颜色值是:QColor(255,239,213);

设置步骤

1:设置btn1对应的状态信息

QState *state1 = new QState;
state1->assignProperty(ui.btn1, "text", QStringLiteral("1选中"));
state1->assignProperty(ui.btn1, "styleSheet", "background-color:编程rgb(255,182,193)");
state1->assignProperty(ui.btn2, "text", QStringLiteral("2"));
state1->assignProperty(ui.btn2, "styleSheet", "background-color:rgb(255,239,213)");
state1->assignProperty(ui.btn3, "text", QStringLiteral("3"));
state1->assignProperty(ui.btn3, "styleSheet", "background-color:rgb(255,239,213)");

代码讲解使用QState::assignProperty,指示此状态在进入状态时将具有给定对象的给定名称的属性设置为给定值。

通俗来说,就是响应状态需要让哪些按钮做什么样的操作。

在响应state1状态时,btn1的文字变成了"1选中",背景颜色也发生了变化,同理,state2、state3也是如此。

2:设置btn2对应的状态信息

QState *state2 = new QState;
state2->assignProperty(ui.btn1, "text", QStringLiteral("1"));
state2->assignProperty(ui.btn1, "styleSheet", "background-color:rgb(255,239,213)");
state2->assignProperty(ui.btn2, "text", QStringLiteral("2选中"));
state2->assignProperty(ui.btn2, "styleSheet", "background-color:rgb(255,182,193)");
state2->assignProperty(ui.btn3, "text",开发者_JAVA教程 QStringLiteral("3"));
state2->assignProperty(ui.btn3, "styleSheet", "background-color:rgb(255,239,213)");

3:设置btn3对应的状态信息

QState *state3 = new QState;
state3->assignProperty(ui.btn1, "text", QStringLiteral("1"));
statandroide3->assignProperty(ui.btn1, "styleSheet", "background-color:rgb(255,239,213)");
state3->assignProperty(ui.btn2, "text", QStringLiteral("2"));
state3->assignProperty(ui.btn2, "styleSheet", "background-color:rgb(255,239,213)");
state3->assignProperty(ui.btn3, "text", QStringLiteral("3选中"));
state3->assignProperty(ui.btn3, "styleSheet",js "background-color:rgb(255,182,193)");

4:设置停止状态

当设置了所有控件对应的状态后,最后需要设置停止状态。停止状态是一个单独的状态类:QFinalState。

QFinalState *stateFinal = new QFinalState;

5:数据绑定

每个单独的状态设置完成后,那么该如何对状态以及按钮做绑定呢?

state1->addTransition(ui.btn1, &QPushButton::clicked, state1);
state2->addTransition(ui.btn2, &QPushButton::clicked, state2);
state3->addTransition(ui.btn3, &QPushButtonphp::clicked, state3);

6:将所有的状态添加到状态机QStateMachine中

QStateMachine *pMachine = new QStateMachine;
pMachine->addState(state1);
pMachine->addState(state2);
pMachine->addState(state3);
pMachine->addState(stateFinal);

7:设置初始化状态

上述工作完成后,必须要给状态机设置初始状态,并且状态必须是这个状态的子状态。

pMachine->setInitialState(state1);

8:开始运行状态

pMachine->start();

好了,根据上述代码,进行调试运行试试?

结果发现,无论点击哪个按钮,按钮都没有反应,原因出到哪里呢?

答:错误是出在了第5步,当前状态是无法绑定自己的,那么该如何实现这种互斥?

对需要进行控件绑定的状态:stat1、state2、state3,设置一个父状态,由父状态来分配数据绑定就可以实现啦。

修改方案

1:创建父状态

QState *stateParent = new QState;

2:每个状态设置父状态

对state1、state2、state3的构造函数中,分别继承自stateParent,修改如下:

QState *state1 = new QState(stateParent);
QState *state2 = new QState(stateParent);
QState *state3 = new QState(stateParent);

3:数据绑定修改

由父状态进行分配状态对应,修改如下:

stateParent->addTransition(ui.btn1, &QPushButton::clicked, state1);
stateParent->addTransition(ui.btn2, &QPushButton::clicked, state2);
stateParent->addTransition(ui.btn3, &QPushButton::clicked, state3);
QFinalState *stateFinal = new QFinalState(stateParent);

并且,初始化父状态的初始子状态

stateParent->setInitialState(state1);

4:状态机数据绑定

此时,不需要将state1、state2、state3直接绑定到pMachine中了,而是将stateParent绑定到pMachine中。

并且,设置状态机pMachine的初始状态是stateParent。

经过如此修改后,调试代码发现,可以实现按钮的互斥效果了,也就是文章开始的动画效果。

在不使用状态时,使用stateFinal进行销毁就可以了。比如在响应关闭按钮时,可以做结束处理

stateParent->ad编程客栈dTransition(ui.btnExit, &QPushButton::clicked, stateFinal);

下面贴出完整代码

Qt利用QState状态机实现控件互斥操作详解

今日份分享就到这里了~

到此这篇关于Qt利用QState状态机实现控件互斥操作详解的文章就介绍到这了,更多相关Qt控件互斥操作内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号