Qt属性系统(Qt's Property System)及在Pyqt中的应用

 

Qt Meta Object system 学习--

Qt属性系统(Qt's Property System)及在Pyqt中的应用

from  http://hi.baidu.com/cyclone/blog/item/fb5c8794ec9d1910d21b70b4.html
by  1+1=2 2010-09-21 14:10


使用

  • 使用 Q_PROPERTY 宏来声明属性(即 将属性注册到meta-object系统中)。
  • 通过QObject的metaObject即可获得用Q_PROPERTY注册的所有属性
    • QMetaObject::property 返回QMetaProperty对象指针
    • QMetaObject::propertyCount 属性个数(包含父类定义的属性)
    • QMetaObject::propertyOffset 属性的开始索引
    • QMetaObject::indexOfProperty 根据属性名得到属性索引
    • QMetaObject::userProperty 带USER的属性,无参数(只能有一个?)
  • 通过QMetaProperty可以获得属性的的各种信息
  • 使用QObjecty可以读取或设置属性
    • property
    • setProperty

Q_PROPERTY

Qt属性是靠 Q_PROPERTY 宏进行声明的

Q_PROPERTY(type name
 READ getFunction
[WRITE setFunction]
[RESET resetFunction]
[NOTIFY notifySignal]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL])
例子:
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(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled USER true)

 

  • READ 该项必须!后接无参的const函数
  • WRITE 后接无返回值的但参数函数
  • RESET 后接无参无返回值的函数
  • NOTIFT 后接单参的信号,属性变化时发射
  • DESIGNABLE 布尔量(默认True),是否在designer中出现
  • SCRIPTABLE 布尔量(默认True),是否用于脚本
  • STORED 布尔量(默认True),是否“不依赖”其他值。比如mimimumWidth 依赖 mimimumSize,故为False
  • USER 布尔量(默认False),是否是直接面向用户的。比如QPushButton的 checked 属性,则为 True
  • CONSTANT 出现则代表常量。不可有 WRITE 及 NOTIFY
  • FINAL 出现则代表不能被派生类重载?

从源代码文件 qobjectdefs.h 中可以看到该宏定义为空

#define Q_PROPERTY(TEXT)

也就是是说该宏仅对 moc 有意义,moc处理后生成的代码在 xxx.moc 或 moc_xxx.cpp 中。

moc

看一个例子:

Q_PROPERTY(bool colorDialog READ colorDialogEnabled WRITE setColorDialogEnabled)

查看对应的moc文件:

  • 索引数据在 static const uint qt_meta_data_QtColorPicker[]

  • 字符串数据在 static const char qt_meta_stringdata_QtColorPicker[]

  • 并在 qt_metacall 函数中生成有相关的代码

动态属性

通过QObject的setProperty 设置属性时,如果该属性不存在,则为设置为动态属性。动态属性存储在QObject中,而不是其QMetaObject对象中。

we would start with this style sheet:

*[mandatoryField="true"] {
    background-color: yellow;
}

Although there is no mandatoryField property defined anywhere in Qt, we can easily create one by callingQObject::setProperty(). Starting with Qt 4.2, setting the value of a non-existent property dynamically creates that property. For example:

nameLineEdit->setProperty("mandatoryField", true);
genderComboBox->setProperty("mandatoryField", true);
ageSpinBox->setProperty("mandatoryField", true);

类型

  • 对于 enum 类型,需要用 Q_ENUMS 或Q_FLAGS 将其注册到 meta-object系统中
  • 对自定义类型,如果要用作属性,需要用 Q_DECLARE_METATYPE()将其注册到meta-object系统中。

对 PySide 及 PyQt4

 

QtCore.pyqtProperty(type, fget=None, fset=None, freset=None, fdel=None, doc=None, designable=True, scriptable=True, stored=True, user=False, constant=False, final=False)

type

 

type of the property

fget

 

getter function

fset

None

setter function

freset

None

function used to reset the value of the property to its default value (only in C++)

fdel

None

function for del'ing the property (only in Python)

doc

None

docstring of the property

designable

True

value of Qt DESIGNABLE flag

scriptable

True

value of Qt SCRIPTABLE flag

stored

True

value of Qt STORED flag

user

False

value of Qt USER flag

constant

False

value of Qt CONSTANT flag

final

False

value of Qt FINAL flag

 

使用举例:
class MyObject(QObject):
  def __init__(self,startval=42):
    self.ppval = startval
  def readPP(self):
    return self.ppval
  def setPP(self,val):
    self.ppval = val
  pp = pyqtProperty(int, readPP, setPP)

obj = MyObject()
obj.pp = 47
print obj.pp

  • PySide用Property来取代pyqtProPerty

  • PySide一开始出现一个失误,用的是QProperty而不是Property

  • PyQt4 为 fget 提供了默认的None,由于Qt要求READ函数必须有,故PySide不为其提供默认值

 

你可能感兴趣的:(PyQt,python,QT)