我研究了qRegisterMetaType()的qt文档,其中指出必须先调用此函数,然后才能在信号/插槽机制中使用相应的类型。但是我找不到任何必须手动完成的代码示例。
This页指出,如果moc可以确定该类型可以被注册为元类型,则该注册将由moc自动完成。看起来这是正确的,因为我测试了QSignalSpy,QObject :: connect()(直接和队列连接)和QVariant-仅使用Q_DECLARE_METATYPE(type),它们都不需要显式调用qRegisterMetaType即可工作。
所以我的问题是:什么时候我必须调用qRegisterMetaType(),否则该代码将无法正常工作?
答案 0 :(得分:0)
Qt文档说,Q_DECLARE_METATYPE对于将连接作为队列连接的情况是必需的。
添加Q_DECLARE_METATYPE()使所有模板都知道该类型 基于功能,包括QVariant。请注意,如果您打算使用 排队的信号和插槽连接或QObject中的类型 物业系统,您还必须调用qRegisterMetaType(),因为 名称在运行时解析。
为此,我构建了一个小型测试应用程序,以举例说明该行为。
只需尝试删除Q_DECLARE_METATYPE(Message)
并注意警告和输出更改。如果连接正常,则似乎不需要该宏。
main.cpp
#include <QApplication>
#include <QThread>
#include "MyHeaderView.h"
Q_DECLARE_METATYPE(Message);
int main(int argc, char **args)
{
QApplication app(argc, args);
{
TestObject sender;
TestObject receiver;
QObject::connect(&sender, &TestObject::sendMessage, &receiver, &TestObject::onMessage);
sender.emitMessage(1, 2);
}
// This requires Q_DECLARE_METATYPE(Message);
QThread workerThread;
TestObject sender2;
TestObject receiver2;
receiver2.moveToThread(&workerThread);
workerThread.start();
QObject::connect(&sender2, &TestObject::sendMessage, &receiver2, &TestObject::onMessage, Qt::ConnectionType::QueuedConnection);
sender2.emitMessage(3, 4);
app.exec();
}
TestObject.h
#pragma once
#include <QObject>
#include <QDebug>
struct Message
{
int x;
int y;
};
class TestObject : public QObject
{
Q_OBJECT
public:
void emitMessage(int x, int y) { emit sendMessage(Message{ x,y }); }
signals:
void sendMessage(const Message&);
public slots:
void onMessage(const Message& m) { qDebug() << m.x << m.y; }
};