qt中使用信号槽来处理GUI与后台数据同步是不错的。耗时的任务可以在处理完数据后使用信号通知UI更新。对于qt中的已有类型,可以直接使用。但,多数时候都需要用到自定义类型。如果像内建类型那样使用,编译时正常,但运行时会报错:
QObject::connect: Cannot queue arguments of type 'xxxx' (Make sure 'xxxx' is registed using qRegisterMetaType().)
原因:在跨线程进行信号槽连接时,为了不阻塞发送信号的线程,一般采用Qt::QueuedConnection
连接类型。这种情形中,当signal被入队时,其参数也会一起入队,这就意味着在slot接收前,需要进行拷贝操作,也就需要通知Qt如何进行拷贝操作。基本类型Qt自动处理,自定义类型就需要一个机制来通知Qt。这就是qRegisterMetaType()
的应用场景。
解决步骤:
- 包含头文件
#include<QMetaType>
- 自定义类型
class MyType{
};
- 在使用前进行注册
qRegisterMetaType<MyType>("MyType");
- 进行连接
connect(sender, SIGNAL(mySignal(MyType)), receiver, SLOT(mySlot(MyType)));
注:
必须进行
#include<QMetaType>
否则会报错:
error: expected constructor, destructor, or type conversion before ‘;’ token
补充:
方法二:
使用Q_DECLARE_METATYPE
原理:Qt的信号机制支持QVariant
类型,Q_DECLARE_METATYPE
使得QVariant
支持自定义类型;
class MyType {
};
Q_DECLARE_METATYPE(MyType);
方法三:
使用Qt::DrectConnection
方式连接信号槽。不推荐,安全性存疑。
connect(sender, SIGNAL(mySignal(MyType)), receiver, SLOT(mySlot(MyType)), Qt::DrectConnection);