QT元对象系统中踩到的坑(qRegisterMetaType的使用)
最近在使用Qt的元对象系统中的注册自定义类为元对象的过程当中踩了一个坑
大概模型是这样
自定义类是在自己的命名空间中,为了摆脱qt依赖,未使用Q_DECLARE_METATYPE
namespace XXX {
class FrameData
{
public:
FrameData(){}
~FrameData(){}
.....
};
}
元对象是在main函数中注册的
int res = qRegisterMetaType<XXX::FrameData>("FrameData");
使用场合是一个跨线程槽函数通讯,会将类对象放到对列中,故要求传递的对象需要是qt的元对象
signals:
void updateFrame(const XXX::FrameData& data);
public slots:
void onUpdateFrame(const XXX::FrameData &data);
感觉一切都没有问题,但是每次运行都无法正常调用槽函数,显示错误
QObject::connect: Cannot queue arguments of type 'OMS::FrameData'
(Make sure 'OMS::FrameData' is registered using qRegisterMetaType().)
困惑了很久也没有找到问题所在,也查阅了很多博主写的文章,并没有相关的介绍
后来尝试了改变注册位置,发现并不是注册的位置。
最后重写了信号和槽函数才发现正确的写法
using namespace XXX;
signals:
void updateFrame(const FrameData& data);
using namespace XXX;
public slots:
void onUpdateFrame(const FrameData &data);
我推测在元对象系统中,在进行对象匹配时候,是字符匹配,原先注册的对象是“FrameData”
那么使用就需要也是“FrameData”,如果加上了命名空间“XXX:FrameData”则会被认定未一个未注册的新元对象,就会提示未被注册的提示
为了验证我将原来的代码修改了
int res = qRegisterMetaType<OMS::FrameData>("XXX::FrameData");
signals:
void updateFrame(const XXX::FrameData& data);
public slots:
void onUpdateFrame(const XXX::FrameData &data);
这种情况下也可以正常调用槽函数
所以在跨命名空间的元对象注册中,一定要切记,注册字符和使用字符一定要保持一致,否则是无法调用槽函数的