我正在尝试了解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中,我可以将一个用户定义的'timeout'事件发布到状态机。我还需要在每次转换时启动一个新计时器。每次转换的动作都发生在QEventTransition的子类中,可能是在'onTransition'方法中。如何将Detector对象传递给这些(唯一的)转换对象中的每一个,以便Detector是一个调用startTimer()的对象?另外,我不确定如何在具有它们的两个转换上实现保护条件。我在QAbstractTransition中看到了虚拟的'eventTest',但是我不太清楚它是如何用来实现一个后卫的。我很确定我的想法不是Qt方式,但是。
我看过Qt我可以找到的两本书(来自Summerfield和Ezust)以及http://doc.qt.io/qt-5/statemachine-api.html#events-transitions-and-guards。这些书根本没有提到QStateMachine。在我看来,Qt在线文档缺少通用状态机的足够示例代码。它很好地展示了如何使用现有信号来创建转换,而不是用户定义的事件。
欢迎任何帮助。感谢。
编辑:我意识到我可以在Detector :: timerEvent()函数中使用基本的switch语句实现我自己的简单状态机。我现在正在这样做,但我仍然非常有兴趣了解如何使用QStateMachine完成此操作。