我在使用enum
類型的信號時遇到了一些問題。基本上我有兩個類,一個狀態機和一個處理狀態機的線程。當狀態改變時,我想發送一個新狀態的信號。我也想用enum
代表國家。在我完整的代碼中,狀態機在單獨的共享庫中實現,但下面的代碼給出了完全相同的錯誤。如何在Qt信號和插槽中使用枚舉
當我運行代碼,我得到了以下行爲:
[email protected]:sigenum $ ./sigenum
Object::connect: No such slot MyThread::onNewState(state)
Test signal
Test signal
...
我已經在我的樣本代碼四個文件:statemachine.h
,statemachine.cpp
,main.h
和main.cpp
。主函數只是啓動線程,然後線程創建StateMachine
的實例並處理來自StateMachine
的信號。我對Qt非常陌生,所以當我意識到必須將枚舉與Q_ENUMS
一起並將其註冊到類型系統時,我感到有些困惑。所以這是完全可能的,我做了一些菜鳥的錯誤
下面的代碼有點長,但我希望它是儘可能類似於我的真實代碼。
statemachine.h
樣子:
// statemachine.h
#ifndef _STATEMACHINE_H
#define _STATEMACHINE_H
#include <QtCore>
class StateMachine : public QObject
{
Q_OBJECT
Q_ENUMS(state)
public:
enum state {S0, S1, S2};
void setState(state newState);
signals:
void stateChanged(state newState);
void testSignal(void);
};
Q_DECLARE_METATYPE(StateMachine::state);
#endif
而且它是這樣實現的:
// statemachine.cpp
#include <QtCore>
#include "statemachine.h"
void StateMachine::setState(state newState)
{
emit stateChanged(newState);
emit testSignal();
}
線被定義爲
// main.h
#ifndef _MAIN_H
#define _MAIN_H
#include <QtCore>
#include "statemachine.h"
class MyThread : public QThread
{
Q_OBJECT
private:
void run(void);
private slots:
void onNewState(StateMachine::state);
void onTestSignal(void);
private:
StateMachine *myStateMachine;
};
#endif
而且它的實現如下:
// main.cpp
#include <QtCore>
#include <QApplication>
#include "statemachine.h"
#include "main.h"
void MyThread::run()
{
myStateMachine = new StateMachine();
qRegisterMetaType<StateMachine::state>("state");
// This does not work
connect(myStateMachine, SIGNAL(stateChanged(state)),
this, SLOT(onNewState(state)));
// But this does...
connect(myStateMachine, SIGNAL(testSignal()),
this, SLOT(onTestSignal()));
forever {
// ...
myStateMachine->setState(StateMachine::S0);
}
}
void MyThread::onTestSignal()
{
qDebug() << "Test signal";
}
void MyThread::onNewState(StateMachine::state newState)
{
qDebug() << "New state is:" << newState;
}
爲了記錄,解決此問題的原因是元對象系統正在根據(標準化)字符串比較來決定信號/插槽的兼容性。它不會「知道」StateMachine :: state和state在這個上下文中引用了相同的類型。 – rohanpm
我不需要QRegisterMetaType使用Qt 4.8,只是完全限定的名字無處不在。 – kikeenrique
得到了一個類似的例子,只需從行'Q_DECLARE_METATYPE(StateMachine :: state)'中刪除分號,就可以明確調用'qRegisterMetaType() – user666412