qt阻塞调不出qmessagebox

qt阻塞调不出qmessagebox,第1张

状态机系统提供了创建和执行状态图的类。这些概念和符号基于Harel的Statecharts: A visual formalism for complex systems(状态图复杂系统的可视化形式),也是UML状态图的基础。状态机执行的语义基于状态图XML(SCXML)。
状态图提供了一个展示建模系统如何对外界刺激作出反应的图形化表示方法。这通过定义系统可能处于状态与系统如何在这些状态之间转变来完成。事件驱动系统的关键特征(例如Qt的应用)是系统的行为一般不单单取决于最后一个或当前的事件,也与之前发生的事件相关。有了状态图这个转换可以简单地表现出来。
状态机框架提供了一个API和执行模型,它们可以用来在Qt应用里高效地嵌入状态图的元素和语义。这个框架与Qt的元对象系统紧密的结合,状态之间的转换可以被信号触发,状态属性可以设置,也可以调用对象方法。Qt的事件系统被用来驱动状态机。
状态机框架里的状态图是层级结构。一个状态可以嵌入另一个状态中,当前状态机的配置是由目前激活的状态集合构成的。一个合法配置的状态机的所有状态都有一个共同的祖先节点
状态机框架中的类
这些类是由Qt提供用来创建状态机。
QAbstractState QStateMachine的状态的基类
QAbstractTransition QAbstractState对象之间转换的基类
QEventTransition QEent之间QObject特定的转换
QFinalState 最终状态
QHistoryState 返回先前激活的子状态的方式
QKeyEventTansition 键盘事件的转换
QMouseEventTransition 鼠标事件的转换
QSignalTransition 基于Qt信号的转换
Qstate QSateMachine的一般目的状态
QStateMachine 等级结构的状态机
QStateMachine::SiganlEvent 表示一个Qt信号事件
QStateMachine::WrappedEvent 继承了QEvent并且持有一个与QObject相关联的事件的复制品
一个简单的状态机
为了表达一个状态机API的核心功能,让我们来看一个简单的例子:一个包含三个状态的状态机,S1,S2和S3。状态机由单个QPushButton控制;当按钮点击,状态机会转换为另一个状态。一开始状态机在状态S1。下面是这个状态机的状态图:
下面这条展示了创建状态机的代码。首先,我们创建状态机和状态:
QStateMachine machine;
QState s1 = new QState();
QState s2 = new QState();
QState s3 = new QState();
然后,我们用QState::addTransition()函数来创建转换:
s1->addTransition(button, &QPushButton::clicked, s2);
s2->addTransition(button, &QPushButton::clicked, s3);
s3->addTransition(button, &QPushButton::clicked, s1);
接下来我们为状态机添加状态,并且设置状态机的初始状态:
machineaddState(s1);
machineaddState(s2);
machineaddState(s3);
machinesetInitialState(s1);
最后,我们启动状态机:
machinestart();
状态机以异步的方式执行,她变为你应用中事件循环的一部分。
在状态进入和离开时做有用的工作
上面的状态机只是在状态之间转换,它没有执行任何 *** 作。当QState::assignProperty()函数可以用来设置一个进入状态时QObject的属性,下面这条展示了在各个状态下OLable的text属性:
s1->assignProperty(label, "text", "In state s1");
s2->assignProperty(label, "text", "In state s2");
s3->assignProperty(label, "text", "In state s3");
当进入任何一个状态时,lable的文字会相应作出改变。
QState::entered()信号会在进入状态时发射,离开时会发射QState::exited()信号。下面的条目展示了当进入S3时按钮的showaximized槽函数会被执行,离开S3时showMinimized()槽函数会被执行:Conversely
QObject::connect(s3, &QState::entered, button, &QPushButton::showMaximized);
QObject::connect(s3, &QState::exited, button, &QPushButton::showMinimized);
定制的状态可以重写QAbstractState::onEntry()和QAbstractState::onExit()
停止状态机
前面小节中定义的状态机不会结束。为了让一个状态机停下来,它需要有一个最高级的最终状态(QFinalState 对象)。当状态机进入了一个最高级的最终状态,状态机会发射一个QStateMachine::finished() 信号并且挂起。
你为一个状态图引入一个最终状态所要做的是创建一个QFinalState对象并且把他作为一个或多个转换的目标。
在分组状态间共享转换
将如我们想要在任何时候通过点击一个离开按钮离开应用程序。为了实现这一目标,我们需要创建一个最终状态并且将它作为一个与离开按钮点击信号相关的转换目标。我们可以为S1,S2,和S3添加转换,但这似乎太繁杂了,而且人们也不得不去记住在未来新加入的状态上加上这些转换。
我们可以通过把S1,S2,S3分为一组来实现这一行为(就是不管状态机处于哪个状态,只要按下离开按钮就能离开状态机)。这可以通过创建一个新的最高级别的状态并且把这三个原来的状态都变成新状态的子状态,下图展示了新的状态机。
三个原来的状态重命名为s11,s12和s13来表现现在他们时新状态s1的子状态。子状态会继承父状态的转换。这意味着在S1和s2之间添加一个转换就已经足够。新加入s1的子状态也将会自动继承这个转换。
需要分组的状态在创建时要指定合适的父状态。你也要指定哪一个状态是初始状态(这是指当父状态变为一个转换的初始状态时状态机一改进入哪一个子节点)。
QState s1 = new QState();
QState s11 = new QState(s1);
QState s12 = new QState(s1);
QState s13 = new QState(s1);
s1->setInitialState(s11);
machineaddState(s1);
QFinalState s2 = new QFinalState();
s1->addTransition(quitButton, &QPushButton::clicked, s2);
machineaddState(s2);
machinesetInitialState(s1);
QObject::connect(&machine, &QStateMachine::finished,
QCoreApplication::instance(), &QCoreApplication::quit);
一个子状态可以从写一个继承的转换,例如,下面的代码添加了一个这样的转换:当状态机处于s2时会直接忽略掉Quit按钮。
s12->addTransition(quitButton, &QPushButton::clicked, s12);
一个转换可以用任意的状态作为他的目标,目标状态不必与源状态的等级一致。
使用历史状态来保存和恢复当前的状态
class StringTransition : public QAbstractTransition
{
Q_OBJECT
public:
StringTransition(const QString &value)
: m_value(value) {}
protected:
bool eventTest(QEvent e) override
{
if (e->type() != QEvent::Type(QEvent::User+1)) // StringEvent
return false;
StringEvent se = static_cast<StringEvent>(e);
return (m_value == se->value);
}
void onTransition(QEvent ) override {}
private:
QString m_value;
};想象一下我们想要为上面讨论的例子添加一个中断机制;用户可以按下按钮来让状态机执行一些无关的任务,完成这个之后状态机也应该从中断中恢复之前正在做的工作(就是回到老的状态中,这个例子里就是s11,s12,和s13)。
这样的行为用历史状态很容易实现。一个历史状态(QHistoryState 对象)是一个伪状态,它表示父状态在退出的最后一刻所处的子状态。
一个历史状态被用来记录我们希望记录的当前的子状态;当状态机在运行时检测到这样一个状态出现时,它会在父状态退出时自动记录当前子状态。到历史状态的转换实际上是到状态机先前保存的子状态的转换;状态机自动地“转向”到真实的子状态的转换。

以上就是关于qt阻塞调不出qmessagebox全部的内容,包括:qt阻塞调不出qmessagebox、、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9618462.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存