Qt Meta Object system 学习--
Qt属性系统(Qt's Property System)及在Pyqt中的应用
from http://hi.baidu.com/cyclone/blog/item/fb5c8794ec9d1910d21b70b4.htmlby 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不为其提供默认值