The property System
和其它编译器厂商一样, Qt 也提供了复杂的属性机制, 但是作为一个编译器无关、平台无关的库,Qt没有那些不被标准编译器支持的特征, 如 BCB的 __property。 Qt 的属性机制在任何平台的任何C++编译器上都能正常使用。 这是由 meta object 提供的。
Qt 属性与C++ 成员变量相同, 但它多了一些由meta object 提供的高级特性。 这通过Q_PROPERTY 关键字实现。 需要注意几点:
如果要在QML中使用属性绑定,必须定义NOTIFY。
USER 表示该属性是否能够被用户编辑。 一般一个类里只有一个USER 为true的属性。 比如 QAbstractButton::checked。 在 QItemDelegate 中能够读取和修改这个属性。
因为在宏里, 逗号表示参数分隔, 因此如果属性是 QMap类型的, 使用QMap 替代 QMap<QString, QVariant>. 为保持一致, QList<QVariant> 通常也使用 QVariantList 。
访问属性可以通过属性的get set 方法, 也可以通过 propertyName 查询。 但是前者有较高的效率并且能够在编译器提供检查。 而后者的优势在于处理那些需要在运行期确定的属性。
在setProperty 时传入不合法的QVariant, 可以删除属性。 QVariant的默认构造函数能提供一个不合法的QVariant。
Q_DECLARE_METATYPE
使用自定义类型时, 需要使用Q_DECLARE_METATYPE 把该类型注册到 meta-object中去。
如果要让一个自定义类型 CustomType 被 QMetaObject 识别, 需要为该类提供一个 默认构造函数, 一个拷贝构造函数, 一个析构函数。 它向QVariant表示自己是Type的一个 自定义类型。因此, 在使用这个宏时, Type 必须已经完成了声明的工作(能够被 Meta Object 识别)。 对于指针类型, 指针所指的类型也必须完成声明工作, 这时, 应该同时使用Q_DECLARE_OPAQUE_POINTER(Type), 可以使该类型的指针也可以被 Meta Object 识别 。
这个宏一般可以放在类的声明之后, 也可以把它放在一个private 的头文件中, 并保证每次QVariant 使用这个类型时, 都能够包含这个头文件。
这个宏能够保证该类型被所有的模板类识别, 如果在Queue Signal中使用该类型,也要先使用这个宏注册。