Jak używać wyliczeń w sygnałach Qt i slotach
Mam problemy z używaniemenum
typy sygnałów. Zasadniczo mam dwie klasy, maszynę stanu i wątek obsługujący automat stanu. Po zmianie stanu chcę wysłać sygnał z nowym stanem. Chcę także reprezentować stan za pomocąenum
. W moim pełnym kodzie program stanów jest zaimplementowany w osobnej bibliotece współdzielonej, ale poniższy kod podaje ten sam błąd.
Po uruchomieniu kodu otrzymuję następujące zachowanie:
kotte@EMO-Ubuntu:sigenum $ ./sigenum
Object::connect: No such slot MyThread::onNewState(state)
Test signal
Test signal
...
W moim przykładowym kodzie mam cztery pliki:statemachine.h
, statemachine.cpp
, main.h
imain.cpp
. Główna funkcja po prostu uruchamia wątek, wątek tworzy następnie instancjęStateMachine
i przetwarza sygnały zStateMachine
. Jestem całkiem nowy w Qt, więc byłem trochę zdziwiony, kiedy zdałem sobie sprawę, że musisz zamknąć enumQ_ENUMS
i zarejestruj go w systemie typów. Więc jest to w pełni możliwe, że popełniłem jakiś nowy błąd
Poniższy kod jest nieco długi, ale chciałem, aby był jak najbardziej podobny do mojego prawdziwego kodu.
statemachine.h
wygląda jak:
// 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
I to jest realizowane jako:
// statemachine.cpp
#include <QtCore>
#include "statemachine.h"
void StateMachine::setState(state newState)
{
emit stateChanged(newState);
emit testSignal();
}
Wątek jest zdefiniowany jako
// 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
I to jest realizowane w następujący sposób:
// 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;
}