2015-06-23 102 views
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: error: C2664: 'QAbstractState::exited' : cannot convert parameter 1 from 'QEvent::Type' to 'QAbstractState::QPrivateSignal' No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

如果我發出我自己的信號與emit nextState();的錯誤是:

ListenState.obj:-1: error: LNK2001: unresolved external symbol "public: void __thiscall ListenState::nextState(void)" ([email protected]@@QAEXXZ)

有觸發變遷理論,從一個狀態到另一個狀態時的方式我處於原始狀態?

+2

有什麼編譯錯誤信息? – Andre

+0

@Andre我更新了帖子,錯誤代碼爲 – zar

+0

第一個錯誤非常簡單 - 你給它的錯誤類型。 emit nextState();應該工作,我想。我想知道你的彙編是否有問題。你在使用標準的qmake嗎?哪個版本的QT? – Andre

回答

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)); 
    } 
};