신호에 enum
유형을 사용할 때 약간의 문제가 있습니다. 기본적으로 상태 시스템과 상태 시스템을 처리하는 스레드라는 두 개의 클래스가 있습니다. 상태가 변경되면 새로운 상태로 신호를 보내려고합니다. 또한 enum
을 사용하여 상태를 나타내려고합니다. 내 완전 한 코드에서 상태 시스템은 별도의 공유 라이브러리에 구현되지만 아래 코드는 똑같은 오류를 제공합니다.Qt 신호 및 슬롯에서 enum을 사용하는 방법
나는 다음과 같은 동작을 얻을 코드를 실행하면 :
[email protected]:sigenum $ ./sigenum
Object::connect: No such slot MyThread::onNewState(state)
Test signal
Test signal
...
내 샘플 코드에서 네 개의 파일이 있습니다 statemachine.h
, statemachine.cpp
, main.h
및 main.cpp
을. main 함수는 단순히 스레드를 시작하고 스레드는 StateMachine
의 인스턴스를 만들고 StateMachine
의 신호를 처리합니다. Qt를 처음 접했기 때문에 열거 형을 Q_ENUMS
으로 묶고 유형 시스템에 등록해야한다는 것을 깨달았을 때 의아해했습니다. 그래서 신참 실수를 저질렀을 가능성이 충분합니다.
아래의 코드는 약간 길지만 가능한 한 실제 코드와 비슷하게 만들고 싶었습니다. 스레드가
// 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
으로 정의된다 그리고이 구현
// statemachine.cpp
#include <QtCore>
#include "statemachine.h"
void StateMachine::setState(state newState)
{
emit stateChanged(newState);
emit testSignal();
}
다음과 같습니다 :
// 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.h
보인다
// 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;
}
기록상, 이것이 문제를 해결하는 이유는 메타 객체 시스템이 (정규화 된) 문자열 비교를 기반으로 신호/슬롯 호환성을 결정하기 때문입니다. StateMachine :: state와 state는이 문맥에서 같은 타입을 참조한다는 것을 "알지 못한다". – rohanpm
Qt 4.8을 사용하는 qRegisterMetaType은 필요하지 않았습니다. 어디에서나 정규화 된 이름을 사용했습니다. – kikeenrique
'Q_DECLARE_METATYPE (StateMachine :: state)'줄에서 세미콜론을 제거하면'qRegisterMetaType()'을 명시 적으로 호출하지 않고도 비슷한 예제를 사용할 수 있습니다. – user666412