如何在Qt信号和插槽使用枚举 [英] How to use enums in Qt signals and slots
问题描述
我在使用 enum
类型的信号时遇到了一些麻烦。基本上我有两个类,状态机和线程处理状态机。当状态改变时,我想发送一个带有新状态的信号。我还想使用枚举
表示状态。在我完整的代码中,状态机在一个单独的共享库中实现,但下面的代码给出了完全相同的错误。
I have some trouble with using enum
types in signals. Basicly I have two classes, a state machine and a thread handling the state machine. When the state is changed I want to send a signal with the new state. I also want to represent the state using an enum
. In my full blown code the state machine is implemented in a separate shared library, but the code below gives the exact same error.
当我运行代码,我得到以下行为:
When I run the code I get the following behaviour:
kotte@EMO-Ubuntu:sigenum $ ./sigenum
Object::connect: No such slot MyThread::onNewState(state)
Test signal
Test signal
...
$ b b
我的示例代码中有四个文件: statemachine.h
, statemachine.cpp
, main.h
和 main.cpp
。主函数只是启动线程,线程然后创建 StateMachine
的一个实例,并处理来自 StateMachine
的信号。我对Qt很新,所以我有点困惑,当我意识到你必须用 Q_ENUMS
包含枚举并注册类型系统。所以这是完全可能的,我犯了一些菜鸟的错误
I have four files in my sample code: statemachine.h
, statemachine.cpp
, main.h
and main.cpp
. The main function simply starts the thread, the thread then creates an instance of the StateMachine
and processes signals from the StateMachine
. I am pretty new to Qt, so I was a bit puzzled when I realised that you have to enclose the enum with Q_ENUMS
and register it with the type system. So It's fully possible that I've made some rookie mistake
下面的代码有点长,但我想它是类似于我的真正的代码尽可能。
The code below is a bit long, but I wanted it to be as similar to my real code as possible.
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;
}
推荐答案
如果我将 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的输入就不能解决这个问题,谢谢: - )
Wouldn't have solved this without the input from drescherjm, thanks :-)
这篇关于如何在Qt信号和插槽使用枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!