我试图了解 QStateMachine 的用法,特别是处理触发转换的用户事件。此外,我想了解实施警卫的最佳方式。我在下面画了一个状态机。它主要是顺序的,不是状态机的一个很好的例子,但它可以达到不阻塞的目的,因为在等待 QProcess 调用的结果时会有延迟。相反,这些延迟作为超时事件异步处理。
状态机在启动时假定没有 rndis 连接,然后定期运行更长的事件序列来检查连接。一旦检测到连接,就会定期运行较短的检查以确保我们仍然连接,如果没有,则返回运行较长的检查。
这是一些不完整的基本设置代码。
// Set up state machine. Do this so that checking for presence
// is non-blocking. Delays are handled by framework.
//
QState* detected = new QState();
QState* notDetected = new QState();
QState* waitForIfDown = new QState();
QState* waitForCdcEther = new QState();
QEvent* timeout = new QEvent(QEvent::Type(EVENT_TIMEOUT));
m_machine.addState(detected);
m_machine.addState(notDetected);
m_machine.addState(waitForIfDown);
m_machine.addState(waitForCdcEther);
// Need to subclass QEventTransition and implement virtuals
// onTransition and eventTest?
detected->addTransition();
notDetected->addTransition();
waitForIfDown->addTransition();
waitForCdcEther->addTransition();
m_machine.setInitialState(notDetected);
m_machine.start();
我可以在 Detector 对象上调用 startTimer,这是代码所在的位置。然后在 Detector::timerEvent 中,我可以将用户定义的“超时”事件发布到状态机。我还需要在每次转换时启动一个新计时器。每个转换的动作将发生在 QEventTransition 的子类中,大概是在“onTransition”方法中。如何将 Detector 对象传递给每个(唯一)转换对象,以便 Detector 是调用 startTimer() 的对象?另外,我不确定如何在具有它们的两个转换上实现保护条件。我在 QAbstractTransition 中看到了虚拟的“eventTest”,但不太了解它如何用于实现防护。我很确定我的想法还不是 Qt 的方式。
我看过我能找到的两本关于 Qt 的书(来自 Summerfield 和来自 Ezust)以及:http ://doc.qt.io/qt-5/statemachine-api.html#events-transitions-and-守卫。这些书根本没有提到 QStateMachine。在我看来,Qt 在线文档缺少足够的通用状态机示例代码。它很好地展示了如何使用现有信号来创建转换,而不是用户定义的事件。
欢迎任何帮助。谢谢。
编辑:我意识到我可以在 Detector::timerEvent() 函数中使用基本的 switch 语句来实现我自己的简单状态机。我现在正在这样做,但我仍然很想了解如何使用 QStateMachine 来完成 。