2015-06-23 167 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)); 
    } 
};