0%

Qt属性系统

1.属性定义

Qt提供了Q_PROPERTY()宏来定义属性,它是基于元对象系统来实现的。作为平台与编译器无关的库,Qt C++程序可以被任何标注你的C++编译器编译。
在QObject的子类中,用宏Q_PROPERTY()定义属性,格式是:

1
2
3
4
5
6
7
8
9
10
11
12
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的属性,用READWRITE来作为属性的读/写操作,还有其他的一些关键字定义属性的一些操作特性。属性的类型可以是QVariant支持的任何类型,也可以用户自定义类型。
Q_PROPERTY宏定义属性的一些主要关键字的意义如下:

  • READ指定一个读取属性值的函数,没有MEMBER关键字时必须设置READ
  • WRITE指定一个设定属性值的函数,只读属性没有WRITE设置。
  • MEMBER指定一个成员变量与属性关联,成为可读可写的属性,无需再设置READWRITE
  • RESET是可选的,用于指定一个设置属性缺省值的函数。
  • NOTIFY是可选的,用于设置一个信号,当属性值变化时发射此信号。
  • DESIGNABLE表示属性是否在Qt Designer里可见,缺省为true
  • CONSTANT表示属性值是一个常数,对于一个对象实例,READ指定的函数返回值是常数,但是每个实例的返回值可以不一样。具有CONSTANT关键字的属性不能有WRITENOTIFY关键字。
  • FINAL表示所定义的属性不能被子类重载。

QWidget 类定义属性的一些例子如下:

1
2
3
4
Q_PROPERTY(bool focus READ hasFocus)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)
Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle NOTIFY windowTitleChanged DESIGNABLE isWindow)

上面最后这个声明包含了NOTIFY windowTitleChanged,表明当windowTitle属性发生变化时,会触发windowTitleChanged信号,相应的信号声明在QWidget中。(this->setProperty("windowTitle", "test"))


关于如何使用NTOIFY和RESET——Qt爱好者


2.动态属性

其中,不管有没有用READWRITE定义接口函数,只要知道属性名称,就可以通过QObject::property()QObject::setProperty()读取和设置属性值。e.x.:

1
2
3
4
QPushButton *button = new QPushButton;
QObject *object = button;
object->setProperty("flat", true);
bool isFlat = object->property("flat");

这就是动态属性,运行时通过setProperty()定义新属性,并用property()查询,它是针对类实例定义的。
在数据表编辑界面上,为了高亮显示一些必填字段,可以在初始化界面为这些字段关联组件定义新的required属性:

1
2
3
4
5
editName->setProperty("required", "true");
comboSex->setProperty("required", "true");
checkAgree->setProperty("required", "true");
// 应用样式定义将必填字段背景颜色设置为亮绿色
*[required="true"] {background-color: lime}

3.类的附加属性

属性系统还有一个宏Q_CLASSINFO(),可以为类的元对象定义“名称——值”信息,如:

1
2
3
4
5
6
7
8
9
class QMyClass:public QObject 
{
Q_OBJECT
Q_CLASSINFO("author", "Wang")
Q_CLASSINFO ("company", "UPC")
Q_CLASSINFO("version ", "3.0.1")
public:
...
};

Q_CLASSINFO()宏定义附加类信息后,可以通过元对象的一些函数获取类的附加信息,如classlnfo(int)获取某个加信息,函数原型定义如下:

1
QMetaClassInfo QMetaObject::classInfo(int index) const

返回值是QMetaClassInfo类型,有name()value()两个函数,可获得类附加信息的名称和值。

1
2
3
4
// 设置附加值
Q_CLASSINFO("First", "Second")
// 输出键值
qDebug() << this->metaObject()->classInfo(0).value() << ": " << this->metaObject()->classInfo(0).name();