我研究过qRegisterMetaType()的qt文档,其中说明必须先调用此函数,然后才能在信号/槽机制中使用相应的类型。但是,我找不到任何必须手动完成此操作的代码示例。
This页面指出,如果moc可以确定该类型可以被注册为元类型,则该注册由moc自动完成。看起来这是对的,因为我只使用Q_DECLARE_METATYPE(类型)测试了QSignalSpy、QObject::connect() (直接和队列连接)和QVariant,它们都不需要显式调用qRegisterMetaType才能工作。
所以我的问题是:什么时候我必须调用qRegisterMetaType(),因为否则代码将无法工作?
发布于 2019-07-01 14:01:47
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();
}测试对象.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; }
};https://stackoverflow.com/questions/56824783
复制相似问题