深入Qt–元对象与属性
元对象与属性
元对象
元对象(meta object)意思是描述另一个对象结构的对象。对应的类为QMetaObject。
元对象系统基于以下3点:
1.以QObject作为基类。
2.类声明的私有区域中,Q_Object宏指令使我们能够使用元对象的特性,比如动态属性、信号、槽等。
3.元对象编译器(**Meta-Object Compiler** moc)为QObject子类生成具有元对象特性的代码。
通过QObject类的一个成员函数获得该类的元对象:
QMetaObject *QObject::metaObject() const
通过这个元对象,进而可以获取一个QObject对象的更多信息:
QMetaObject::className() 返回运行时类的名称(不需要C++中的运行时类型识别机制RTTI)
QMetaObject::methodCount() 返回类中方法的个数。
类型识别
C++中使用dynamic_cast和typeid这两个运算符进行运行时类型识别(RTII),但是Qt提供另外两种运行时类型识别方法: qobject_cast 和 QObject::inherits()
看名字就可以知道,这两个方法都是基于QObject的,也就是元对象系统。
属性
所谓属性,也就是类中的一个数据成员,我们可以获取(get)和设置(set)。
属性的类型
属性的类型可以是bool、QString、QRect等等,我们可以通过 QVariant::Type 的枚举值获得所有可用于属性的类型。
它不支持枚举类型,但可以通过 Q_ENUM 来设置。即enum TYPE{xx, xx, x,x,}; Q_ENUM(TYPE);
Q_PROPERTY(TYPE type READ type WRITE settype NOTIFY type Changed)
自定义的类型也是不支持的,需要通过 Q_DECLARE_METATYPE 注册元类型。
属性的读与写
可以直接使用get和set方法来读写属性,也可以通过QObject与QMetaObject来间接地读写属性。
通过对应类的成员函数设置,也可以通过 QObject::setProperty() 对其进行设置。
通过对应类的成员函数获取,也可以通过 QObject::property() 来获取属性,它的返回值是 QVariant 类型的,通过 canConvert() 进行判断,然后将其转换为所需的类型。
invokeMethod()
Qt中的信号槽机制是以元对象为基础的,通过名称以类型安全的方式来间接调用槽函数。
当调用槽函数时,实际是由invokeMethod()完成的。
如何将成员变量注册进元对象系统,那么对于成员函数,该怎么做呢?在声明一个类的成员函数时,通过使用 Q_INVOKABLE 宏进行注册,可以使它们能够被元对象系统调用。
自定义属性
在一个继承自QObject的类中使用 Q_PROPERTY 宏指令,比如:
Q_PROPERTY(bool focus READ hasFocus)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY(QColor color MEMBER m_color NOTIFY colorChanged)
然后就可以这样用:
setProperty(“enabled”,true);