什么时候必须调用qRegisterMetaType()?

时间:2019-06-30 12:17:49

标签: qt

我研究了qRegisterMetaType()的qt文档,其中指出必须先调用此函数,然后才能在信号/插槽机制中使用相应的类型。但是我找不到任何必须手动完成的代码示例。

This页指出,如果moc可以确定该类型可以被注册为元类型,则该注册将由moc自动完成。看起来这是正确的,因为我测试了QSignalSpy,QObject :: connect()(直接和队列连接)和QVariant-仅使用Q_DECLARE_METATYPE(type),它们都不需要显式调用qRegisterMetaType即可工作。

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

1 个答案:

答案 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; }
};