Qt 何时必须调用qRegisterMetaType()?

Qt 何时必须调用qRegisterMetaType()?,qt,Qt,我已经研究了qt文档,其中说明在信号/插槽机制中使用相应类型之前必须调用此函数。但是,我找不到任何必须手工完成的代码示例 page声明,如果moc可以确定该类型可以注册为元类型,则该注册由moc自动完成。看起来这是对的,因为我测试了QSignalSpy、QObject::connect()(直接和排队连接)和QVariant,只使用了Q_DECLARE_元类型(type),它们都不需要显式调用qRegisterMetaType来工作 所以我的问题是:我什么时候必须调用qRegisterMetaT

我已经研究了qt文档,其中说明在信号/插槽机制中使用相应类型之前必须调用此函数。但是,我找不到任何必须手工完成的代码示例

page声明,如果moc可以确定该类型可以注册为元类型,则该注册由moc自动完成。看起来这是对的,因为我测试了QSignalSpy、QObject::connect()(直接和排队连接)和QVariant,只使用了Q_DECLARE_元类型(type),它们都不需要显式调用qRegisterMetaType来工作

所以我的问题是:我什么时候必须调用qRegisterMetaType(),因为否则代码将无法工作?

Qt文档说,如果一个连接是排队连接,那么这是必要的

添加Q_DECLARE_METATYPE()会使所有模板都知道该类型 基于函数,包括QVariant。请注意,如果您打算使用 排队信号和插槽连接或QObject中的类型 属性系统中,还必须调用qRegisterMetaType(),因为 名称在运行时解析

为此,我构建了一个小的测试应用程序,它演示了这种行为

只需删除
Q\u DECLARE\u元类型(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();
}
#包括
#包括
#包括“MyHeaderView.h”
Q_DECLARE_元类型(消息);
int main(int argc,char**args)
{
QApplication应用程序(argc、args);
{
测试对象发送器;
测试对象接收器;
QObject::connect(&sender,&TestObject::sendMessage,&receiver,&TestObject::onMessage);
发送者。发送消息(1,2);
}
//这需要Q_DECLARE_元类型(消息);
QThread-workerThread;
testobjectsender2;
测试对象接收器2;
receiver2.moveToThread(&workerThread);
workerThread.start();
QObject::connect(&sender2,&TestObject::sendMessage,&receiver2,&TestObject::onMessage,Qt::ConnectionType::QueuedConnection);
发送者2.发出消息(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; }
};
#pragma一次
#包括
#包括
结构消息
{
int x;
int-y;
};
类TestObject:公共QObject
{
Q_对象
公众:
void emitMessage(intx,inty){emit sendmages(Message{x,y});}
信号:
无效发送消息(常量消息&);
公众时段:

void onMessage(const Message&m){qDebug()我知道Q_DECLARE_元类型,但实际问题是,在什么情况下需要调用qRegisterMetaType()。QSignalSpy和QObject::connect()都可以在不调用qRegisterMetaType()的情况下工作。那么我什么时候必须这样做呢?谢谢你的例子。我承认这对我来说是新的,我认为Q_DECLARE_元类型对于任何连接都是必要的,而不仅仅是队列连接。不幸的是,当用户必须调用qRegisterMetatype时,这仍然不能回答问题。我问这个问题,因为我们有代码,其中对qRegisterMetatype的调用都是ov呃,就是这个地方。如果它们不是真正需要的,我们可以清理代码。正如您的示例所示,它可以在不调用qRegisterMetatype的情况下工作,因为connect本身就可以做到这一点。那么,如果qRegisterMetatype是自动完成的,为什么qRegisterMetatype甚至在那里而没有内部Qt函数呢?