c++ - 当 Q_GADGET 结构位于单独的头文件中时,在 QML 中出现“未注册的数据类型”错误
问题描述
我有一个自定义struct
,我将其用作派生类Q_PROPERTY
中的类型。QMediaPlayer
但这里的代码:
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
}
这有点像魅力,但这里有一个转折点:如果我将声明的声明复制并粘贴struct
到宏的单独头文件中(并且显然包含它)Q_DECLARE_METATYPE
,我会收到以下错误:
QMetaProperty::read: Unable to handle unregistered datatype 'VideoMeta' for property 'FrameProvider::videoMeta'
所以我有两个问题:
- 不太重要的:为什么我需要使用
Q_DECLARE_METATYPE
宏,如果文档说我不需要Q_GADGET
宏,因为它会自动注册类型? - 更重要的是:为什么我不能将声明移到另一个头文件中?我错过了什么?
提前致谢!
编辑:
这可能是相关的:我在 Visual Studio (MSVC v142) 项目中使用 Qt v5.15。(不在 Qt Creator 中。)
解决方案
Q_GADGET
主要用途是允许非 QObject 类型进行自省。
Q_GADGET 宏是 Q_OBJECT 宏的轻量级版本,适用于不从 QObject 继承但仍希望使用 QMetaObject 提供的某些反射功能的类。就像 Q_OBJECT 宏一样,它必须出现在类定义的私有部分中。
Q_GADGET 可以有 Q_ENUM、Q_PROPERTY 和 Q_INVOKABLE,但它们不能有信号或槽。
Q_GADGET 使类成员 staticMetaObject 可用。staticMetaObject 是 QMetaObject 类型,并提供对使用 Q_ENUMS 声明的枚举的访问。
它没有说明注册类型。
也不Q_DECLARE_METATYPE
注册类型,但声明它。
要注册VideoMeta
,您需要致电qRegisterMetaType<VideoMeta>()
。Qt 文档特别指出qRegisterMetaType<T>()
必须调用类型才能在 Qt 属性系统中工作。
此外,要将类型 T 与 QObject::property() API 一起使用,必须在使用之前调用 qRegisterMetaType(),通常在使用 T 的类的构造函数中或在 main() 函数中。
推荐阅读
- firebase - 如何在 Firebase 实时数据库中执行大量删除
- azure - 用于迁移数百万个文件的 Azure LogicApp
- ios - 自动获取 iPhone 应用 UUID 以进行分发
- java - 在spring boot miroservice中使用jackson api时出现Json转换错误
- python - 为什么 discord.py 不能识别“on_message()”之外的变量?
- keycloak - 如何在 Keycloak 中调试身份提供者的问题?
- c# - 检查飞机是否与其他飞机的位置/旋转相同
- google-sheets - 如何计算 Google Query 的数据字段?
- python - 选择特定下拉菜单项时在 tkinter 中添加/更改/删除元素
- go - 在标准输出线程上并发写入是安全的吗?