【问题标题】:Subclassing and modifying QStateMachine子类化和修改 QStateMachine
【发布时间】:2017-08-17 23:36:20
【问题描述】:

假设我有一组运行QStateMachine 的机器人。这些机器人的所有状态机都具有相同的基本结构:

  • 状态:
    • 睡觉
    • 搜索
    • 销毁
    • 返回
  • 转换 (from -> to on signal:
    • 睡眠 -> 搜索“下一个”
    • 搜索 -> 销毁“下一个”
    • 销毁 -> 搜索“下一个”
    • 销毁 -> “返回”返回
    • 搜索 -> “返回”返回
    • 返回 -> 搜索“下一个”
    • 返回 -> 睡在“后面”

// base.h

#include <QObject>
#include <QState>
#include <QStateMachine>

class Base : public QObject
{
    Q_OBJECT
public:
    Base(QObject* parent = 0);
    ~Base();

signals:
    void next();
    void back();

private:
    QStateMachine m_machine;
    QState* m_sleep;
    QState* m_search;
    QState* m_destroy;
    QState* m_return;
};

// base.cpp

Base::Base(QObject* parent) : QObject(parent)
{
    m_sleep = new QState(&m_machine);
    m_search = new QState(&m_machine);
    m_destroy = new QState(&m_machine);
    m_return = new QState(&m_machine);

    m_machine.setInitialState(m_sleep);

    m_sleep->addTransition(this, &Base::next, m_search);
    m_search->addTransition(this, &Base::next, m_destroy);
    m_search->addTransition(this, &Base::back, m_return);
    m_destroy->addTransition(this, &Base::next, m_search);
    m_destroy->addTransition(this, &Base::back, m_return);
    m_return->addTransition(this, &Base::next, m_search);
    m_return->addTransition(this, &Base::back, m_sleep);

    m_machine.start();
}

现在我想要一个更具体的机器人。假设他在破坏过程中更详细,具有几个子状态,例如dismantel -&gt; sprayWithAcid -&gt; blowUp -&gt; desintegrate,他在每个next-signal 上继续前进,或者他在back-signal 上继续return

如前所述,我的计划是将它们作为子状态添加到状态 destroy,但信号 next 不仅会继续子状态机直到完成,还会离开父状态。

我怎样才能避免这种情况?或者还有其他类似的好方法吗?

【问题讨论】:

    标签: c++ qt qt5 qstatemachine


    【解决方案1】:

    我现在明白了。

    诀窍是显式地创建转换,将它们作为类的成员。您可以像这样设置它们:

    m_sleepSearch = new QSignalTransition(this, &Base::next, m_sleep);
    m_searchDestroy = new QSignalTransition(this, &Base::next, m_search);
    m_searchReturn = new QSignalTransition(this, &Base::back, m_search);
    m_destroySearch = new QSignalTransition(this, &Base::next, m_destroy);
    m_destroyReturn = new QSignalTransition(this, &Base::back, m_destroy);
    m_returnSearch = new QSignalTransition(this, &Base::next, m_return);
    m_returnSleep = new QSignalTransition(this, &Base::back, m_return);
    
    m_sleepSearch->setTargetState(m_search);
    m_searchDestroy->setTargetState(m_destroy);
    m_searchReturn->setTargetState(m_return);
    m_destroySearch->setTargetState(m_search);
    m_destroyReturn->setTargetState(m_return);
    m_returnSearch->setTargetState(m_search);
    m_returnSleep->setTargetState(m_sleep);
    

    我的第一个错误是 QSignalTransition(sender, signal, source_state) 构造函数的参数错误,因为它与 -&gt;addTransition(sender, signal, target_state) 的语法过于相似,所以我混淆了 sourcetarget

    在像这样创建它们之后,在子类化这个对象时应该很容易重新路由或禁用其中一些转换。

    【讨论】:

      猜你喜欢
      • 2015-09-25
      • 2016-10-05
      • 2013-12-12
      • 1970-01-01
      • 2020-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多