当 Q_GADGET 结构位于单独的头文件中时,在 QML 中出现 'unregistered datatype' 错误

Getting 'unregistered datatype' error in QML when Q_GADGET struct is in a separate header file

我有一个自定义 struct,我将其用作 QMediaPlayer 派生 class 中的 Q_PROPERTY 类型。但这是代码:

struct VideoMeta
{
    Q_GADGET

    Q_PROPERTY(int width MEMBER width)
    Q_PROPERTY(...)
    ....

public:

    int width;
    ...
};

Q_DECLARE_METATYPE(VideoMeta)

class FrameProvider : public QMediaPlayer
{
    Q_OBJECT

    Q_PROPERTY(VideoMeta videoMeta READ getVideoMeta WRITE setVideoMeta NOTIFY videoLoaded)

    VideoMeta m_videoMeta;

    ...
}

我在 Label:

中使用它
Label {
    text: "Cached frames: " + cacheLoaded + " / " + frameProvider.videoMeta.framecount
}

这很有魅力,但转折点来了: 如果我使用 Q_DECLARE_METATYPE 宏将 struct 的声明复制并粘贴到单独的头文件(显然包含它)中,我会收到以下错误:

QMetaProperty::read: Unable to handle unregistered datatype 'VideoMeta' for property 'FrameProvider::videoMeta'

所以我有两个问题:

  1. 不太重要的:为什么我需要使用Q_DECLARE_METATYPE宏,如果documentation says我不需要用Q_GADGET宏因为它会自动注册类型?
  2. 更重要的是:为什么我不能将声明移到另一个头文件中?我错过了什么?

提前致谢!

编辑:

这可能是相关的: 我在 Visual Studio (MSVC v142) 项目中使用 Qt v5.15。 (不在 Qt Creator 中。)

Q_GADGET主要用途是允许非QObject类型进行内省。

The Q_GADGET macro is a lighter version of the Q_OBJECT macro for classes that do not inherit from QObject but still want to use some of the reflection capabilities offered by QMetaObject. Just like the Q_OBJECT macro, it must appear in the private section of a class definition.

Q_GADGETs can have Q_ENUM, Q_PROPERTY and Q_INVOKABLE, but they cannot have signals or slots.

Q_GADGET makes a class member, staticMetaObject, available. staticMetaObject is of type QMetaObject and provides access to the enums declared with Q_ENUMS.

它没有说明有关注册类型的任何内容。

另外Q_DECLARE_METATYPE不注册一个类型,而是声明它。

要注册 VideoMeta,您需要致电 qRegisterMetaType<VideoMeta>()。 Qt 文档明确指出,必须调用 qRegisterMetaType<T>() 才能使类型在 Qt 属性 系统中工作。

Also, to use type T with the QObject::property() API, qRegisterMetaType() must be called before it is used, typically in the constructor of the class that uses T, or in the main() function.

https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType-1