如何以及何时使用 Q_DECLARE_METATYPE

How and when to use Q_DECLARE_METATYPE

我需要在整个项目中将 QSqlRecord 转换为 QVariant 并返回。为此,我添加了

Q_DECLARE_METATYPE(QSqlRecord);

在需要转换的 classes 的 .h 文件中。 我还有一个基础 class,其中有几个 children 继承自该基础,在这种情况下,我认为在基础 class 中只包含一次 Q_DECLARE_METATYPE 就足够了。因此,我有例如:

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

Redefinition of 'QMetaTypeId<QSqlRecord>

来自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");

根据我对 Q_DECLARE_METATYPE 的理解,这意味着如果我声明它,它会导致错误,因为它已经在其他地方声明过,但如果我不声明它,我就不能从QVariant,因为它无法将 object 识别为有效的 QVariant,我错过了什么?

您在 classes 上使用 Q_DECLARE_METATYPE,具有 public 构造函数、析构函数、复制构造函数,因此 QSqlRecord 适合。只需确保此宏在每个 class 声明中只使用一次。可能你错过了一些 #pragma once?

您自己使用它 classes,在声明 class 之后,在命名空间大括号之外:

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

Q_DECLARE_METATYPE(MyNamespace::MyStruct)

在此处查看文档:http://doc.qt.io/qt-5/qmetatype.html#Q_DECLARE_METATYPE

您应该只将 Q_DECLARE_METATYPE(QSqlRecord) 放在一个 header 中,然后将其包含在需要的任何地方。 Q_DECLARE_METATYPE(QSqlRecord) 必须在任何 类 和命名空间之外。 From Qt documentation:

Ideally, this macro should be placed below the declaration of the class or struct. If that is not possible, it can be put in a private header file which has to be included every time that type is used in a QVariant