Как использовать перечисления в сигналах и слотах Qt

У меня есть некоторые проблемы с использованием enum вводит сигналы. В основном у меня есть два класса, конечный автомат и поток, обрабатывающий конечный автомат. Когда состояние меняется, я хочу отправить сигнал с новым состоянием. Я также хочу представлять государство с помощью enum, В моем полном коде конечный автомат реализован в отдельной общей библиотеке, но код ниже дает точно такую ​​же ошибку.

Когда я запускаю код, я получаю следующее поведение:

kotte@EMO-Ubuntu: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;
}

16

Решение

Используя везде полные имена, я получил его на работу

Если я изменю декларацию stateChanged() в

signals:
void stateChanged(StateMachine::state newState);

И регистрирует тип с

qRegisterMetaType<StateMachine::state>("StateMachine::state");

а также использует это имя в connect заявление

connect(myStateMachine, SIGNAL(stateChanged(StateMachine::state)),
this, SLOT(onNewState(StateMachine::state)));

Не решил бы это без участия от drescherjm, спасибо 🙂

16

Другие решения

Я считаю, что следующее состояние не определено в вашем классе MyThread.

Используйте следующее

подключиться (myStateMachine, SIGNAL (stateChanged (StateMachine :: state)),
this, SLOT (onNewState (StateMachine :: state)));

Редактировать:

Может быть, это будет работать

подключиться (myStateMachine, SIGNAL (stateChanged (state)),
this, SLOT (onNewState (StateMachine :: state)));
4

Вы должны избавиться от SIGNAL а также SLOT поскольку Qt может обнаруживать несоответствия во время компиляции. Вы также можете избежать необходимости использовать Q_DECLARE_METATYPE а также qRegisterMetaType() используя Q_ENUM вместо Q_ENUMS — это было введено в Qt 5.5, наконец enum class это строго типизированная версия enum:

// statemachine.h
#ifndef _STATEMACHINE_H
#define _STATEMACHINE_H

#include <QtCore>

class StateMachine : public QObject
{
Q_OBJECT
Q_ENUM(state)

public:
enum class state {S0, S1, S2};

void setState(state newState);

signals:
void stateChanged(state newState);
void testSignal(void);
};

#endif

// main.cpp
#include <QtCore>
#include <QApplication>

#include "statemachine.h"#include "main.h"
void MyThread::run()
{
myStateMachine = new StateMachine();

connect(myStateMachine, &StateMachine::stateChanged, this, &MyThread::NewState);

connect(myStateMachine, &StateMachine::testSignal, this, &MyThread::onTestSignal);

forever {
// ...
myStateMachine->setState(StateMachine::S0);
}
}
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector