1
    class ListenState : public QState
    {
    public:
        ListenState();
        ~ListenState();

    signals:
        void nextState();

    public slots:
        void getSettings();
    };

cpp文件是

ListenState::ListenState()
{
    qDebug() << "Entering ListenState";
}

ListenState::~ListenState()
{
    qDebug() << "Leaving ListenState";
}

void ListenState::getSettings()
{
    Commands cmd;

    cmd.getSettings();

    emit exited( QEvent::None ); // i want to change state now
}

我想要做的是当getSettings()被调用时,我想将状态更改为下一个。我以为我会emit exited(),但它没有建立。我试图创建自己的信号nextState(),但如果我在这个函数中发出,它也不会编译。

使用上面的代码,错误是:

ListenState.cpp:23: 错误: C2664: 'QAbstractState::exited' : 无法将参数 1 从 'QEvent::Type' 转换为 'QAbstractState::QPrivateSignal' 没有可以执行此转换的用户定义转换运算符,或无法调用操作员

如果我发出自己的信号,emit nextState();错误是:

ListenState.obj:-1:错误:LNK2001:未解析的外部符号“public:void __thiscall ListenState::nextState(void)”(?nextState@ListenState@@QAEXXZ)

当我处于原始状态时,有没有办法触发从一个状态到另一个状态的转换?

4

1 回答 1

3

首先,状态的生命周期与进入或退出状态的时间关系不大。只要状态机存在,状态通常就存在,或者它们可以即时创建和销毁。您正在连接状态的构造函数和析构函数,期望在进入或退出状态时调用它们。不是这种情况。

要检查状态何时进入或退出,您可以使用以下命令:

void exposeStateTransitions(QState * state, QString name) {
  if (name.isEmpty()) name = state->objectName();
  QObject::connect(state, &QState::entered, []{
    qDebug() << "state" << name << "was entered";
  });
  QObject::connect(state, &QState::exited, []{
    qDebug() << "state" << name << "was exited";
  });
}

其次,状态只能通过使用转换对象来改变。您需要为所需的转换创建一个转换对象,并提供一个信号或事件来触发它:

class ListenState : public QState {
  Q_OBJECT
  QSignalTransition m_transition;
  Q_SIGNAL void settingsTransition();
public:
  ListenState(QState * settingsTarget, QState * parent = 0) : 
    QState(parent), m_transition(this, SIGNAL(settingsTransition())
  {
    m_transition.setTargetState(settingsTarget);
    addTransition(&m_transition);
  }
  void getSettings() {
    ...
    emit settingsTransition();
  }
};

如果您愿意,您也可以即时触发转换:

class ListenState : public QState {
  Q_OBJECT
  QSignalTransition m_transition;
  Q_SIGNAL void settingsTransition();
public:
  ListenState(QState * parent = 0) : 
    QState(parent), m_transition(this, SIGNAL(settingsTransition())
  {
    addTransition(&m_transition);
  }
  void getSettings(QState * target) {
    ...
    m_transition.setTargetState(target);
    emit settingsTransition();
  }
};

您可以使用事件而不是信号:

class ListenState : public QState {
  QEventTransition m_transition;
public:
  ListenState(QState * parent = 0) : 
    QState(parent), m_transition(this, QEvent::Leave) {
    addTransition(&m_transition);
  }
  void getSettings(QState * target) {
    ...
    m_transition->setTargetState(target);
    QCoreApplication::postEvent(this, new QEvent(QEvent::Leave));
  }
};
于 2015-06-23T17:14:58.420 回答