Qtilities:属性浏览器的自定义属性类型?

时间:2015-08-10 22:06:39

标签: c++ qt qproperty

我正在编写一个程序,要求用户在处理给定对象上的数据时非常灵活。我想我会使用某种属性浏览器; Qtilities' ObjectDynamicPropertyBrowser引起了我的注意。

但是,我需要能够添加自己的数据类型。文档不清楚如何这样做。

如何允许我自己的数据类型在Qtilities中表示'属性浏览器小部件?

此外,更多关于我的需求:

  • 数据类型不是Qt的一部分,甚至也不是Q_OBJECT s。
  • 不能选择对相关类别进行特定于Qt的修改。
  • 通过Q_DECLARE_METATYPE声明相关课程是可以的。
  • 特别是,我需要表示向量和矩阵类型(可能稍后)。

1 个答案:

答案 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,它基本上是属性浏览器的功能,当然也没有正确的序列化。

有三个步骤。首先,您需要解决没有结构但表示单个值(例如日期,时间或地理位置等)的简单自定义类型,或简单值的集合(例如矩阵) )。

  1. 确保QVariant可以包含简单类型。在接口(头文件)中的类型定义后面添加Q_DECLARE_METATYPE宏。

  2. 实施delegates for the types。对于具有表结构的类型(例如矩阵),您可以利用QTableView并提供将类型的内容公开为表模型的适配器模型。

  3. 其次,您将了解具有内部结构的复杂类型:

    1. 创建一个派生类,它派生自复杂类型,使用Q_PROPERTY声明所有属性,并且具有Q_GADGET宏(不是Q_OBJECT,因为它们不是QObjects)。这类不应该有自己的成员。它唯一的方法应该是可选的属性访问器。 Q_GADGET宏添加静态(类)成员staticMetaObject

    2. 如果需要,底层类型可以是static_cast到包装类,但通常不需要。

    3. 此时,您编写包装器的任何类都可以直接访问QMetaProperty系统,而无需进行强制转换!您将使用包装器的staticMetaObject作为其静态元对象,但QMetaProperty readOnGadgetwriteOnGadget将直接指向基类。

    4. 第三,由于ObjectPropertyBrowser很可能没有在Qt 5.5中实现对小工具的支持,因为这是非常新的,你必须修改它以提供这样的支持。更改将是最小的,与使用QMetaProperty::readOnGadgetQMetaProperty::writeOnGadget而不是QMetaProperty::readQMetaProperty::write有关。请参阅serialization answer以了解两者之间的比较。