2013-02-05 33 views
2

我遇到了一些問題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,所以我不知道那裏有什麼問題。有沒有人對如何讓這個例子起作用有什麼想法?

+0

您是否嘗試在添加轉換之前將狀態添加到狀態機? – Jay

回答

2

沒有什麼像start()插槽QState - 但它存在於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(); 
}; 

它工作得很好。

+0

謝謝,這工作!當我寫這個時,我一定在查看'QStateMachine'插槽。 – Kiril

+0

我的榮幸!另外,我認爲沒有必要發出'finished()',因爲「當輸入最終子狀態('QFinalState')時,狀態發出'QState :: finished()'信號。」。 –

+0

嗯,我注意到...工作就像一個魅力:) – Kiril