当 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'
所以我有两个问题:
- 不太重要的:为什么我需要使用
Q_DECLARE_METATYPE
宏,如果documentation says我不需要用Q_GADGET
宏因为它会自动注册类型?
- 更重要的是:为什么我不能将声明移到另一个头文件中?我错过了什么?
提前致谢!
编辑:
这可能是相关的:
我在 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.
我有一个自定义 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'
所以我有两个问题:
- 不太重要的:为什么我需要使用
Q_DECLARE_METATYPE
宏,如果documentation says我不需要用Q_GADGET
宏因为它会自动注册类型? - 更重要的是:为什么我不能将声明移到另一个头文件中?我错过了什么?
提前致谢!
编辑:
这可能是相关的: 我在 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.