Verwendung von Aufzählungen in Qt-Signalen und Slots
Ich habe Probleme mit der Verwendungenum
Signale eintippen. Grundsätzlich habe ich zwei Klassen, eine Zustandsmaschine und einen Thread, der die Zustandsmaschine behandelt. Wenn sich der Zustand ändert, möchte ich ein Signal mit dem neuen Zustand senden. Ich möchte den Staat auch mit einem. Vertretenenum
. In meinem vollständigen Code ist die Zustandsmaschine in einer separaten gemeinsam genutzten Bibliothek implementiert, aber der folgende Code gibt genau den gleichen Fehler.
Wenn ich den Code ausführe, tritt folgendes Verhalten auf:
kotte@EMO-Ubuntu:sigenum $ ./sigenum
Object::connect: No such slot MyThread::onNewState(state)
Test signal
Test signal
...
Ich habe vier Dateien in meinem Beispielcode:statemachine.h
, statemachine.cpp
, main.h
undmain.cpp
. Die Hauptfunktion startet einfach den Thread, der Thread erzeugt dann eine Instanz desStateMachine
und verarbeitet Signale von derStateMachine
. Ich bin ziemlich neu in Qt, also war ich ein bisschen verwirrt, als mir klar wurde, dass Sie die Aufzählung mit einschließen müssenQ_ENUMS
und beim Typensystem registrieren. Es ist also durchaus möglich, dass ich einen Anfängerfehler gemacht habe
Der folgende Code ist etwas lang, aber ich wollte, dass er meinem tatsächlichen Code so ähnlich wie möglich ist.
statemachine.h
sieht aus wie:
// 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
Und es ist implementiert als:
// statemachine.cpp
#include <QtCore>
#include "statemachine.h"
void StateMachine::setState(state newState)
{
emit stateChanged(newState);
emit testSignal();
}
Der Thread ist definiert als
// 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
Und es ist wie folgt implementiert:
// 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;
}