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