【问题标题】:Unable to start state and transition between states: receiving various errors无法启动状态和状态之间的转换:收到各种错误
【发布时间】:2013-02-07 12:26:06
【问题描述】:

我在使用Qt State Machine. 时遇到了一些问题,我永远无法执行这些状态:我遇到了各种类型的错误,但我不知道问题出在哪里。有关错误和导致错误的代码的更多信息,请参阅下文。

这是我的主要功能:

int main(int argc, char *argv[])
{
    // Initialize the app
    // ... app initialization here
    QApplication app(argc, argv);

    // Create the state machine
    QStateMachine machine;

    MyState* ms1 = new MyState("ms1");
    MyState* ms2 = new MyState("ms2");
    QFinalState* fs = new QFinalState();

    ms1->addTransition(ms2);
    ms2->addTransition(fs);

    machine.addState(ms1);
    machine.addState(ms2);
    machine.addState(fs);
    machine.setInitialState(ms1);

    QObject::connect(&machine, SIGNAL(finished()), new Finisher(), SLOT(OnFinished()));
    machine.start();
    return app.exec();
}

我在MyState 中设置了断点,但是断点永远不会被击中,并且start/stop 方法永远不会执行(我实际上只希望start 被调用)。应用程序直接进入Finisher::OnFinished 方法。

这是我的状态类:

class MyState: public QState
{
    Q_OBJECT
private:
    QString _stateName;
public:
    MyState(QString stateName, QState * parent = 0):QState(parent), _stateName(stateName){}
    ~MyState(){}

public slots:
    void start()
    {
        qDebug() << _stateName << " start.";
        emit finished();
    }

    void stop()
    {
        qDebug() << _stateName << " stop.";
    }

signals:
    void finished();
    //void exited();
};

终结者非常简单:

class Finisher:public QObject
{
    Q_OBJECT
    public slots:
    void OnFinished()
    {
        qDebug() << "Finished!";
        QTimer::singleShot(0, QApplication::instance(), SLOT(quit()));
    }
};

我尝试了几件事,包括直接设置每个状态的父级:

// If I use the following code, I get an error 
// stating that "the state has already been added to this machine"
MyState* ms1 = new MyState("ms1");
MyState* ms2 = new MyState("ms2", ms1);
QFinalState* fs = new QFinalState(ms2);

ms1->addTransition(ms2);
ms2->addTransition(fs);

machine.addState(ms1);
machine.addState(ms2);
machine.addState(fs);
machine.setInitialState(ms1);
// .. and so on

但是,当调用 machine.addState 时,我似乎无法添加状态:

QStateMachine::addState: state has already been added to this machine
QStateMachine::addState: state has already been added to this machine
Unrecoverable error detected in running state machine: Missing initial state in
compound state ''

我也试过只留下构造函数而不调用machine.addState

QStateMachine machine;
MyState* ms1 = new MyState("ms1");
MyState* ms2 = new MyState("ms2", ms1);
QFinalState* fs = new QFinalState(ms2);

ms1->addTransition(ms2);
ms2->addTransition(fs);
machine.setInitialState(ms1);
// .. and so on

但是,在这种情况下,我收到以下错误:

QState::setInitialState: state 0xa05e5e0 is not a child of this state (0x43fe94)

QStateMachine::start: No initial state set for machine. Refusing to start.

最后一个很奇怪,因为我明确将初始状态声明为ms1,然后我调用start,所以我不知道那里有什么问题。有人对如何让这个例子起作用有任何想法吗?

【问题讨论】:

  • 您是否尝试在添加转换之前将状态添加到状态机?

标签: c++ qt runtime-error qstatemachine


【解决方案1】:

QState 中没有类似 start() 的插槽 - 但它存在于 QStateMachine 中。

我想你想重新实现

virtual void    onEntry ( QEvent * event )
virtual void    onExit ( QEvent * event )

方法:

class MyState: public QState
{
    Q_OBJECT
private:
    QString _stateName;
public:
    MyState(QString stateName, QState * parent = 0):QState(parent), _stateName(stateName){}
    ~MyState(){}

protected:
   virtual  void onEntry(QEvent * event)
    {
        qDebug() << _stateName << " start.";
    }

   virtual  void onExit(QEvent * event)
    {
        qDebug() << _stateName << " stop.";
    }
signals:
    void finished();
    //void exited();
};

效果很好。

【讨论】:

  • 谢谢,这行得通!我写的时候一定是在看QStateMachine 插槽。
  • 我的荣幸!另外,我认为没有必要发出finished(),因为“当进入最终子状态(QFinalState)时,状态会发出QState::finished()信号。”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-05
  • 2020-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多