Qt线程间信号槽传递自定义数据类型(qRegisterMetaType的使用)
#include <QMetaType>
CFileDataModel::CFileDataModel(QObject *parent) : QAbstractItemModel(parent)
{
//初始化根节点
init();
//指针和引用类型的参数都用如下方式注册,
//qRegisterMetaType<CFileData>("CFileData&")这种方式注册不行
qRegisterMetaType<CFileData>("CFileData");
//rpc获取数据的线程和model绑定
connect(m_pGetDataThread, SIGNAL(updateData(CFileData*)), this, SLOT(onGetFileData(CFileData*)));
}
#include <QMetaType>
CFileDataModel::CFileDataModel(QObject *parent) : QAbstractItemModel(parent)
{
//初始化根节点
init();
//指针和引用类型的参数都用如下方式注册,
//qRegisterMetaType<CFileData>("CFileData&")这种方式注册不行
qRegisterMetaType<CFileData>("CFileData");
qRegisterMetaType<QHash<int, CFileData*>>("QHash<int, CFileData*>&");
//qRegisterMetaType<QVector<int>>("QVector<int>");
//rpc获取数据的线程和model绑定
connect(m_pGetDataThread, SIGNAL(updateData(QHash<int, CFileData*>&)),
this, SLOT(onGetFileData(QHash<int, CFileData*>&)));
}
【注】
不跨线程的话,使用自定义的类型使用signal/slot来传递,没有什么问题。但如果是跨线程的使用,则没有这么简单。
直接使用的话,会产生下面这种错误:(假定自定义类为MyClass)
QObject::connect: Cannot queue arguments of type 'MyClass' (Make sure 'MyClass' is registed using qRegisterMetaType().)
实际运行中也会发现,该信号槽没有起作用。
其实解决方法在错误提示中已经给出了:Make sure 'MyClass' is registed using qRegisterMetaType().
即使用qRegisterMetaType()将自定义类型进行注册。
使用方法如下:
1. 注册位置:在第一次使用此类链接跨线程的signal/slot之前,一般在当前类的构造函数中进行注册;
2. 注册方法:在当前类的顶部包含:
#include <QMetaType>,构造函数中加入代码:qRegisterMetaType<MyClass>("Myclass");
如果不实用这种方法,还有一种办法来使跨线程的signal/slot起作用,即使用connect函数的Qt::DirectConnection参数。
connect(A,SIGNAL(sendA(MyClass)),B,SLOT(getA(MyClass)),Qt::DirectConnection);
但此方法官方不推荐使用,认为其不安全。不过在笔者实际使用过程中,未发现有不妥之处。