属性系统
属性基础
- 属性和数据成员相似。他们的差别在于存取的方式不同,比如属性值通常使用读取函数(get)和设置函数(set)来存取。除此之外QT还有其他方式存取属性值。
- 在QT中属性和数据成员是两个不同概念,他们可以有联系也可以没有联系。比如名为a的属性和数据成员a,他们名称相同,但是完全不想管。
- 属性值可以通过下面的方式存取
- 可以使用 QObject::property 和 QObject::setProperty 函数进行存取
- 属性还可以通过元对象系统的QMetaObject来存取
- 若属性有相关联的存取函数,则可以使用存取函数来存取
QVariant 类
-
使用QObject::property函数可以读取属性值,使用QObject::setProperty 函数可以设置属性
的值。但是数据类型有很多种,怎么使得property返回的值属于正确的类型呢?QT使用的QVariant 类 -
QVariant 类用于封装数据成员和值,类似于UNION ,QVariant 对象一次只能保存单一类型的值。
-
QVariant 具有常用类型的单形参构造函数,所以可以把这些常用数据类型转换为QVariant 类型。也可以直接赋值。
QVariant v(1) v=2.2
-
获取 QVariant 对象存储的值的类型
-
Type type() const
获取 QVariant 对象当前存储值的类型,类型以枚举 QMetaType::Type 的形式表示
-
const char * typeName() const;
以字符串的形式返回QVariant对象存储值的类型。
-
-
获取和设置QVariant对象的值
-
void setValue(const T& v);
-
T value() const;
把存储对象转换为T类型
-
T toT()
例如int toInt()
-
使用QObject类中的成员函数存取属性值 和动态属性
-
QVariant QObject::property(const char* name) const;
获取属性名称为name的值
-
bool QObject::setProperty(const char* name, const QVariant & v);
把属性name值设置为v 并且返回true
动态属性
- 若属性没有使用Q_PROPERTY进行声明,就直接把属性添加到对象中,并且返回false,这就是动态属性
- 动态属性可以使用property进行查询
- 动态属性是基于某个类的实例的,也就是说动态属性是添加到某个对象中的,而不是添加到QMetaObject中的,这意味着,无法使用QMetaObject获得动态属性的值。
- 更改动态属性的值,会发送QDynamicPropertyChangeEvent到该对象。
使用反射机制获取属性值
这些属性必须是Q_PROPERTY声明的
-
QMetaProperty类
函数 说明 const char* name() const; 获取属性的名称 const char* typeName() const; 返回该属性的类型名称 QVariant::Type type() const; 返回属性类型 int userType() const; 返回属性的用户类型 int propertyIndex() const; 返回属性的索引 QMetaEnum enumerator() const 属性是否为枚举类型 QVariant read(const QObject* object) const; 从给性对象读取属性值 bool write(QObject* object, const QVariant & v) const; 将属性值写到指定对象中 bool reset(QObject* object) const; 重置 bool hasNotifySignal() const; 属性是否有通知信号 QMetaMethod notifySignal() const; int notifySignalIndex() const; 返回属性通知信号的索引 -
QMetaObject类中与属性相关的成员函数
函数 说明 int indexOfProperty(const char* name) const; 返回属性的索引 int propertyCount() const; 返回属性的数量(包括从父类继承的属性) int propertyOffset() const; 返回父类的属性数量 QMetaProperty property(int index) const; 返回索引的元数据 QMetaProperty userProperty() const; 返回USER标志为true的属性的元数据