【问题标题】:How and when to use Q_DECLARE_METATYPE如何以及何时使用 Q_DECLARE_METATYPE
【发布时间】:2017-03-16 09:09:01
【问题描述】:

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

Q_DECLARE_METATYPE(QSqlRecord);

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

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

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

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 转换,因为它没有将对象识别为有效的 QVariant,我缺少什么?

【问题讨论】:

    标签: c++ qt qmetatype


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回复,我确实将 Q_DECLARE_METATYPE 放在了命名空间之外,但是它位于另一个类的 .h 文件中。我是否应该只创建一个包含我需要的所有 Q_DECLARE_METATYPE 的特定 .h 文件,并在需要时包含它?
    • 来自 Qt 文档的@NicoloCastro >理想情况下,这个宏应该放在类或结构的声明之下。如果这是不可能的,它可以放在一个私有头文件中,每次在 QVariant 中使用该类型时都必须包含该头文件。
    • 好的,谢谢,抱歉,我浏览了一下,显然没有注册该段落。
    【解决方案2】:

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

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

    //mystruct.h
    namespace MyNamespace
    {
    struct MyStruct
    {
        int i;
        ...
    };
    }
    
    Q_DECLARE_METATYPE(MyNamespace::MyStruct)
    

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

    【讨论】:

    • 为什么我不应该在 Qt 的类上使用声明元类型?如何将 QVariant 转换为 Qt 类?还是不应该允许我这样做?
    • 抱歉,我从文档中刷新了我的信息并快速修复了答案。
    • 哦,好的,谢谢。所以在我写的我知道我会强制转换的类中,我可以将声明直接放在同一个文件中,在命名空间之外,对于其他人我必须包含它,但这是我的问题,现在如果我包含它告诉我它已经包含(重新定义'QMetaTypeId)如果我删除它,它告诉我我没有声明它。
    • 这看起来你的 .h 文件确实缺少包含保护(#pragma once 或 #ifndef FILENAME #define FILENAME)
    猜你喜欢
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2013-06-12
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2018-06-21
    相关资源
    最近更新 更多