类似于其他一些GUI编译器,Qt提供了一个复杂的属性系统。然而,Qt提供的这套类库是与编译器、以及与操作系统无关的,适用于Qt支持平台下的任何标准C++编译器。
属性系统依赖于元对象系统(Meta Object Sytstem)(关于元对象系统,请见我上一篇文章从零开始学Qt - 10:一文读懂Qt的元对象系统)。
本文对Qt的属性系统的基础知识进行了介绍,让你一文读懂属性系统。
一、属性是什么?
属性是指描述一个窗口或控件的某个方面性质的参数。比如,对于一个类QWidget的窗口对象,属性objectName表示了窗口实例的名称,属性geometry表示窗口的位置和大小。
Qt Creator设计界面右下角的属性编辑面板,显示了当前选中控件的一些属性的“名称-值”。从共同父类继承而来的控件,有一些继承自父类的共同属性,也可能有一些自身独有的属性。
另外,Qt中的控件有自带的属性,我们也可以自己定义属性。
二、属性怎么定义?
Qt提供一个Q_PROPERTY()宏可以定义属性,它也是基于元对象系统实现的。在QObject的子类中,Q_PROPERTY的详细使用格式如下:
Q_PROPERTY(type name
(READ getFunction [WRITE setFunction] |
MEMBER memberName [(READ getFunction | WRITE setFunction)])
[RESET resetFunction]
[NOTIFY notifySignal]
[REVISION int]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL])
Q_PROPERTY宏定义一个返回值类型为type,名称为name的属性,用READ、WRITE关键字定义属性的读取、写入函数,还有其他的一些关键字定义属性的一些操作和特性。一些主要关键字的说明如下([]内为可选关键字):
关键字 | 说明 |
READ | 指定一个读取属性值的函数。如果没有MEMBER关键字,则必须设置READ。 |
WRITE | 指定一个设置属性值的函数,对于只读属性不可设置。 |
MEMBER | 指定一个成员变量与属性关联,成为可读可写属性,无需设置READ和WRITE。 |
RESET | 是可选的,用于指定一个设置缺省值的函数。 |
NOTIFY | 是可选的,用于设置一个当属性值发生变化时发射的信号。 |
DESIGNABLE | 表示属性是否在Qt Designer里可见,默认为true。 |
CONSTANT | 表示一个实例对象的属性值是一个常数,但每一个实例的返回值(通过READ指定函数的返回值)可以不同。具有这个关键字则不能有WRITE和NOTIFY关键字。 |
FINAL | 表示所定义的属性不能被子类重载。 |
上述Q_PROPERTY定义关键字虽然较多,但实际使用时可能只需设置一部分关键字即可。例如QWidget类定义属性的几个例子如下:
Q_PROPERTY(bool focus READ hasFocus)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
三、属性的使用
(1)如果利用READ或WRITE定义了接口函数,那么利用该函数可以实现属性值的读取或设置。
(2)另外,不管是否利用READ和WRTIE定义了接口函数,只要知道了属性的名称,就可以通过QObject::property()读取属性值,通过QObject::setProperty()设置属性值。例如,
QObject *obj = new QPushButton;
obj->setProperty(“flat”, true); // 设置flat为true
bool isFlat = obj->property(“flat”); // 读取flat属性
四、动态属性是什么?
Q_PROPERTY()宏是在类的定义中实现的,对于类的所有实例对象都有效,可以称之为静态属性。
相对地,利用QObject::setProperty()函数,也可以在运行时为类定义一个新的属性,称之为动态属性。动态属性是针对类的实例定义的。使用方法很简单,
setProperty(const char * name, const QVariant & value);
其中,第一个参数是属性的名称,第二个参数是属性值。
动态属性也可以使用QObject::property()查询,就如在类定义里使用Q_PROPERTY宏定义的属性一样。
五、类的附加信息
属性系统还有一个宏Q_CLASSINFO(),可以为类的元对象定义“名称-值”附加信息,如
class QMyClass : public QObject
{
Q_OBJECT
Q_CLASSINFO(“author”, ”future”); // 定于author为future
Q_CLASSINFO(“version”, “1.0.0”); // 定义version为1.0.0
...
}
用Q_CLASSINFO定义附加类信息后,可以通过元对象的一些函数获取类的附加信息。例如,
QMyClass *myClass = new QMyClass;
const QMetaObject *meta = myClass->metaObject(); // 获取元对象
for(int i=meta->classInfoOffset(); iclassInfoCount; i++)
{
QMetaClassInfo ci= meta->classInfo(i); // 获取附加信息
qDebug() << QString( “Name=%1; Value=%2” ).arg(ci.name()).arg(ci.value());
}
觉得有用的话,希望大家多多关注评论转发[赞],谢谢!
留言与评论(共有 0 条评论) “” |