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;
}

Antworten auf die Frage(3)

Ihre Antwort auf die Frage