我正在编写一个程序,要求用户在处理给定对象上的数据时非常灵活。我想我会使用某种属性浏览器; Qtilities' ObjectDynamicPropertyBrowser
引起了我的注意。
但是,我需要能够添加自己的数据类型。文档不清楚如何这样做。
如何允许我自己的数据类型在Qtilities中表示'属性浏览器小部件?
此外,更多关于我的需求:
Q_OBJECT
s。Q_DECLARE_METATYPE
声明相关课程是可以的。答案 0 :(得分:1)
您引用的浏览器取决于QObject
属性系统。所以,除非你的类是QObjects,否则它将无法工作 - 但不要绝望,Qt 5.5拯救(继续阅读)。浏览器似乎使用QTreeView
并提供了一个公开QObject
属性系统的适配器模型。因此,它利用了Qt的类型和委托系统。
在Qt 5.5中,只要存在描述该类的QMetaObject
,就可以在任何类上使用通用属性系统(称为gadgets)。通过将Q_GADGET
宏添加到从主题类派生的类中,并使用Q_PROPERTY
宏描述属性,您可以利用moc
和小工具系统来访问未修改类型的属性。
您这样做的唯一原因是需要对ObjectPropertyBrowser
系统进行最少的更改。您不需要ObjectDynamicPropertyBrowser
,因为它适用于动态属性,而您的对象没有任何属性。它们具有静态属性,通过Q_PROPERTY
宏和moc生成的代码给出。
因此,您将继续像对QVariant
和一般视图实施自己的类型支持一样。您还需要Qt 5.5,因为您需要小工具支持才能工作。 Qt 5.4及以下版本的解决方案需要采用不同的方法,并且以另一种方式实施可能不那么麻烦。
有关使用小工具属性系统进行对象序列化的参考,请参阅this answer,它基本上是属性浏览器的功能,当然也没有正确的序列化。
有三个步骤。首先,您需要解决没有结构但表示单个值(例如日期,时间或地理位置等)的简单自定义类型,或简单值的集合(例如矩阵) )。
确保QVariant
可以包含简单类型。在接口(头文件)中的类型定义后面添加Q_DECLARE_METATYPE
宏。
实施delegates for the types。对于具有表结构的类型(例如矩阵),您可以利用QTableView
并提供将类型的内容公开为表模型的适配器模型。
其次,您将了解具有内部结构的复杂类型:
创建一个派生类,它派生自复杂类型,使用Q_PROPERTY
声明所有属性,并且具有Q_GADGET
宏(不是Q_OBJECT
,因为它们不是QObjects)。这类不应该有自己的成员。它唯一的方法应该是可选的属性访问器。 Q_GADGET
宏添加静态(类)成员staticMetaObject
。
如果需要,底层类型可以是static_cast
到包装类,但通常不需要。
此时,您编写包装器的任何类都可以直接访问QMetaProperty
系统,而无需进行强制转换!您将使用包装器的staticMetaObject
作为其静态元对象,但QMetaProperty
readOnGadget
和writeOnGadget
将直接指向基类。
第三,由于ObjectPropertyBrowser
很可能没有在Qt 5.5中实现对小工具的支持,因为这是非常新的,你必须修改它以提供这样的支持。更改将是最小的,与使用QMetaProperty::readOnGadget
和QMetaProperty::writeOnGadget
而不是QMetaProperty::read
和QMetaProperty::write
有关。请参阅serialization answer以了解两者之间的比较。