You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt状态机中如何实现选择分支?有没有更易维护的实现方案?

最优实现方案

Qt的状态机框架本身已经提供了足够灵活的扩展能力,你只需要实现1次通用的条件过渡类,之后所有选择逻辑都可以直接复用,不需要重复编写子类。

第一步:实现通用可复用的条件过渡类

#include <QAbstractTransition>
#include <functional>

class ConditionTransition : public QAbstractTransition
{
public:
    explicit ConditionTransition(std::function<bool()> judgeFunc, QState *source = nullptr)
        : QAbstractTransition(source), m_judge(std::move(judgeFunc)) {}

protected:
    // 过渡触发判断逻辑
    bool eventTest(QEvent *event) override {
        Q_UNUSED(event)
        return m_judge ? m_judge() : false;
    }
    void onTransition(QEvent *event) override { Q_UNUSED(event) }

private:
    std::function<bool()> m_judge;
};

第二步:直接使用该类实现选择逻辑

你只需要给状态S1添加两个该类的实例,分别对应判断条件为真/假的分支即可:

// 示例:假设已经初始化好了状态S1、S2、S3,以及判断函数checkCondition()
// 条件为真时跳转到S2
auto *trueBranch = new ConditionTransition(checkCondition);
trueBranch->setTargetState(S2);
S1->addTransition(trueBranch);

// 条件为假时跳转到S3
auto *falseBranch = new ConditionTransition([]{ return !checkCondition(); });
falseBranch->setTargetState(S3);
S1->addTransition(falseBranch);

更简化的场景方案

如果你的选择逻辑不需要等待额外事件触发,是进入S1后立刻执行判断,还可以省去自定义过渡类的步骤:

// 绑定S1的进入信号,直接判断后切换状态
connect(S1, &QState::entered, [=]{
    checkCondition() ? S1->machine()->setCurrentState(S2) : S1->machine()->setCurrentState(S3);
});

基于信号触发的选择方案

如果选择逻辑是在收到某个特定信号后触发,你连自定义类都不需要,直接用QSignalTransition自带的守卫功能即可:

// 示例:当对象obj发出ready()信号时执行选择判断
auto *trueBranch = new QSignalTransition(obj, &YourClass::ready);
trueBranch->setGuard(checkCondition);
trueBranch->setTargetState(S2);
S1->addTransition(trueBranch);

auto *falseBranch = new QSignalTransition(obj, &YourClass::ready);
falseBranch->setGuard([]{ return !checkCondition(); });
falseBranch->setTargetState(S3);
S1->addTransition(falseBranch);

以上几种方案都只需要写一次通用逻辑,后续所有选择场景都可以直接复用,不会出现重复编写子类的冗余问题,维护成本极低。

内容的提问来源于stack exchange,提问作者Tim Meyer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 02:45:04