如何以及何时使用Q_DECLARE_METATYPE

Nic*_*tro 8 c++ qt qmetatype

我需要将QSqlRecord转换为QVariant并返回整个项目.为了做到这一点,我补充道

Q_DECLARE_METATYPE(QSqlRecord);
Run Code Online (Sandbox Code Playgroud)

在需要强制转换的类的.h文件中.我还有一个基类,几个子节点从中继承,在这种情况下,我假设在基类中只包含一次Q_DECLARE_METATYPE就足够了.因此,我有例如:

  • widgetBaseClass:声明元类型
  • widgetChildClass1:inherits widgetBaseClass不声明元类型
  • widgetChildClass2:inherits widgetBaseClass不声明元类型
  • myTableModel:声明元类型

当我尝试像这样运行程序时,我得到了

Redefinition of 'QMetaTypeId<QSqlRecord>
Run Code Online (Sandbox Code Playgroud)

来自widgetBaseClass,指向myTableModel中的上一个声明.如果另一方面我删除了我得到的声明:

static_assert failed "Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system");
Run Code Online (Sandbox Code Playgroud)

从我如何理解Q_DECLARE_METATYPE的工作方式来看,这意味着如果我声明它,它会导致错误,因为它已经在其他地方声明了,但是如果我没有声明它我无法从QVariant转换,因为它无法识别对象作为一个有效的QVariant,我错过了什么?

Mat*_*szL 7

Q_DECLARE_METATYPE在具有公共构造函数、析构函数、复制构造函数的类上使用,因此 QSqlRecord 适合。只要确保这个宏在每个类声明中只使用一次。也许你错过了一些#pragma once

在你自己的类上使用它,在类声明之后,在命名空间大括号外:

//mystruct.h
namespace MyNamespace
{
struct MyStruct
{
    int i;
    ...
};
}

Q_DECLARE_METATYPE(MyNamespace::MyStruct)
Run Code Online (Sandbox Code Playgroud)

请参阅此处的文档:http : //doc.qt.io/qt-5/qmetatype.html#Q_DECLARE_METATYPE


em2*_*2er 6

您应该将Q_DECLARE_METATYPE(QSqlRecord)放在一个标题中,然后只需将它包含在它所需的位置.Q_DECLARE_METATYPE(QSqlRecord)必须位于任何类和名称空间之外. 从Qt文档:

理想情况下,此宏应放在类或结构的声明下面.如果这是不可能的,可以将它放在一个私有头文件中,每次在QVariant中使用该类型时都必须包含该文件