Como usar enums em sinais e slots Qt
Eu tenho alguns problemas com o usoenum
tipos em sinais. Basicamente eu tenho duas classes, uma máquina de estados e um thread lidando com a máquina de estados. Quando o estado é alterado, quero enviar um sinal com o novo estado. Eu também quero representar o estado usando umenum
. No meu código completo, a máquina de estados é implementada em uma biblioteca compartilhada separada, mas o código abaixo dá exatamente o mesmo erro.
Quando executo o código, obtenho o seguinte comportamento:
kotte@EMO-Ubuntu:sigenum $ ./sigenum
Object::connect: No such slot MyThread::onNewState(state)
Test signal
Test signal
...
Eu tenho quatro arquivos no meu código de exemplo:statemachine.h
, statemachine.cpp
, main.h
emain.cpp
. A função principal simplesmente inicia o encadeamento, o encadeamento então cria uma instância do encadeamentoStateMachine
e processa sinais doStateMachine
. Eu sou muito novo no Qt, então fiquei um pouco perplexo quando percebi que você tem que incluir o enum comQ_ENUMS
e registre-o no sistema de tipos. Então é totalmente possível que eu tenha cometido algum erro de novato
O código abaixo é um pouco longo, mas eu queria que ele fosse o mais semelhante possível ao meu código real.
statemachine.h
parece:
// 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
E é implementado como:
// statemachine.cpp
#include <QtCore>
#include "statemachine.h"
void StateMachine::setState(state newState)
{
emit stateChanged(newState);
emit testSignal();
}
O encadeamento é definido como
// 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
E é implementado da seguinte forma:
// 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;
}