背景:
【qt信号槽-1】槽函数重写问题,qt_metacall和qt_static_metacall
【qt信号槽-3】(QObject::connect: No such slot)的一种解决方法,connect函数qt4/qt5格式,元数据注册
【qt信号槽-4】槽函数不响应不执行的一种原因:ui提升导致重名
信号槽参数使用了自定义枚举,运行报错。先看代码:
class Exec_Multi_Sample : public Exec_Multi_Base
{
Q_OBJECT
public:
enum EState { ... } m_eState;
private slots:
void onSetState(EState e);
...
};
Q_DECLARE_METATYPE(Exec_Multi_Sample::EState)
自认为已经注意了相关事宜。但还是运行报错QObject::connect: No such slot。
解决:
在定义枚举的类当中,引用该枚举也要写全类名,像这样:
class Exec_Multi_Sample : public Exec_Multi_Base
{
Q_OBJECT
public:
enum EState { ... } m_eState;
private slots:
void onSetState(Exec_Multi_Sample::EState e);//就是这里
...
};
Q_DECLARE_METATYPE(Exec_Multi_Sample::EState)
当然,在实现文件.cpp里面也要这样写,然后就没问题了。
分析:
之前在各涉及到该信号槽的地方,除了槽函数的声明和定义,其它地方都写全了类名“Exec_Multi_Sample::”,当然connect也是如此。看来是qt没有足够智能解决这个问题。纵使再有什么原理,我个人认为,在类的内部,理论上类名应该可以省略。
追加(另一种解决方法):
关于connect函数的用法,之前我都是使用qt4的语法:
connect(sender, SIGNAL(mySignal(parameters)), receiver, SLOT(mySlot(parameters)));
最初的想法,一方面是习惯,另一方面可以很明确看到参数列表,当需要重载的时候就比较好用。信号槽没有参数时,这种写法比qt5格式简短。但缺点是,当查找信号或者槽的引用时,qt creator找不到connect这里。至少我尝试的情况是这样的。
后来全部改为qt5格式:
connect(sender, &senderClass::mySignal, receiver, &receiverClass::mySlot);
当信号槽没有参数时,因为有类名和双冒号,写出来太长。但优点是,在查找信号槽引用时,qt creator可以定位到connect这里。
之所以要提到connect格式,是改用qt5格式以后,之前“(QObject::connect: No such slot)”的问题貌似没有了。
另外涉及到元数据类型注册的问题,还要记录一下。
元数据注册:
Q_DECLARE_METATYPE():
亲测需要写在类外面,此时当然参数中需要写全类型名,加上类名和双冒号。
Q_ENUM:
手册说,需要类已经使用过 Q_OBJECT/Q_GADGET/Q_ENUM_NS(),我的理解是,继承在QObject的类使用它。亲测可以写在类里面,直接写在枚举定义的后面就行,不用写类名加双冒号。
qRegisterMetaType<MyClass>("MyClass"):
qRegisterMetaType<MyClass>():
自定义类型用于信号槽时,需要执行它。使用过Q_DECLARE_METATYPE/Q_ENUM的类型,用于信号槽时,需要执行它。
本文完。