乒乓国家

乒乓状态示例展示了如何在Qt State Machine Framework 中将并行状态与自定义事件和转换结合使用。

该示例实现了一个状态图,其中两个状态通过向状态机发布事件进行通信。状态图如下

pingerponger 状态是并行状态,即它们同时进入并独立进行转换。

pinger 状态进入后将发布第一个ping 事件;ponger 状态将响应发布pong 事件;这将导致pinger 状态发布新的ping 事件;以此类推。

class PingEvent : public QEvent
{
public:
    PingEvent() : QEvent(PingEventType) { }
};

class PongEvent : public QEvent
{
public:
    PongEvent() : QEvent(PongEventType) { }
};

定义了两个自定义事件:PingEventPongEvent

classPinger :publicQState
{public:explicitPinger(QState*父节点)  QState(parent) { }protected:voidonEntry(QEvent*) override { machine()->postEvent(newPingEvent);        qInfo() << "ping?";
    };

Pinger 类定义了一个状态,当进入该状态时,它会向状态机发布一个PingEvent

classPingTransition :publicQAbstractTransition
{public: PingTransition() {}protected:booleventTest(QEvent*e) override {return  e->type()==PingEventType; }voidonTransition(QEvent*) override { machine()->postDelayedEvent(newPongEvent, 500);        qInfo() << "pong!";
    };

PingTransition 类定义了一个由PingEvent 类型的事件触发的转换,并在触发转换时向状态机发布PongEvent (延迟 500 毫秒)。

classPongTransition :publicQAbstractTransition
{public: PongTransition() {}protected:booleventTest(QEvent*e) override {return(e->type()==PingEventType); }voidonTransition(QEvent*) override { machine()->postDelayedEvent(newPingEvent, 500);        qInfo() << "ping?";
    };

PongTransition 类定义了一个由PongEvent 类型的事件触发的转换,并在触发转换时向状态机发布PingEvent (延迟 500 毫秒)。

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    QStateMachine machine;
    auto group = new QState(QState::ParallelStates);
    group->setObjectName("group");

main() 函数首先创建了一个状态机和一个并行状态组。

    auto pinger = new Pinger(group);
    pinger->setObjectName("pinger");
    pinger->addTransition(new PongTransition);

    auto ponger = new QState(group);
    ponger->setObjectName("ponger");
    ponger->addTransition(new PingTransition);

接着,创建pingerponger 状态,并将并行状态组作为其父状态。请注意,转换是无目标的。当触发这种转换时,源状态不会退出或重新进入;只有转换的 onTransition() 函数会被调用,而状态机的配置将保持不变,这正是我们在本例中想要的。

    machine.addState(group);
    machine.setInitialState(group);
    machine.start();

    return app.exec();
}

最后,将组添加到状态机中,启动状态机,并进入应用程序事件循环。

示例项目 @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.