Qt属性系统(Qt Property System)
Qt提供了巧妙的属性系统,它与某些编译器支持的属性系统相似。然而,作为平台和编译器无关的库,Qt不能够依赖于那些非标准的编译器特性,比如__property 或者 [property]。Qt的解决方案能够被任何Qt支持的平台下的标准C++编译器支持。它依赖于元对象系统(Meta_Object Sytstem),元对象系统通过信号和槽提供了对象间通讯的机制。
1. Qt中怎么声明属性?
QObject中的子类的私有域中使用Q_PROPERTY宏来声明一个属性
以下是来自QWidget类的一些属性声明
Q_PROPERTY(bool focus READ hasFocus)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor) 以下例子展示了如何使用MEMBER关键字将类数据成员导出为Qt属性。注,NOTIFY signal必须被指定,这样才能被QML使用
Q_PROPERTY(QColor color MEMBER m_color NOTIFY colorChanged)
Q_PROPERTY(qreal spaing MEMBER m_spacing NOTIFY spaingChanged)
Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)
...
signals:
void colorChanged();
void spacingChanged();
void textChanged(const QString &netText); private:
QColor m_color;
qreal m_spacing;
QString m_text;
2. 对QT中属性的理解
一个属性的表现就像一个普通的数据成员一样,但是它有额外提供元对象系统访问的特性
(1)如果MEMBER关键子没有被指定,则一个READ访问函数是必须的,它被用来访问数据成员的值。它的返回类型必须是属性类型或者属性类型的常引用。比如,QWidget::focus是一个只读的属性,通过读函数,QWidget::hadFocus访问。
(2)一个WRITE函数是可选的,它被用来设置数据成员的值。的返回类型必须是void,而且仅能有一个参数,其类型必须是属性类型或者是属性类型的指针类型或者是属性类型引用。例如,QWidget::enabled有一个WRITE函数,QWidget::setEnabled(bool)。只读属性不需要WRITE函数。比如QWidget::focus就没有WRITE函数。
(3)如果属性没有READ访问函数,则需要用MEMBER指定成员变量,这使得给定的成员变量在没有创建READ和WRITE的函数下可读可写。如果你需要控制变量的访问权限,也可以使用READ和WRITE函数而不仅仅是MEMBER,注意别同时使用。
(4)一个RESET函数页是可选的,它被用来将属性设置为上下文指定的默认值,例如,QWidget::cursor有READ和WRITE函数,QWidget::cursor() QWidget::setCursor(),同时它也有一个RESET函数QWidget::unsetCursor(),因为没有可用的setCursor调用可以确定的将cursor属性重置为上下文默认的值。RESET函数必须返回void类型,而且不带参数。
(5)NOTIFY也是可选的。如果定义了NOTIFY则需要指定一个已经存在的信号,该信号在属性值发生改变是发射。与属性相关的信号必须有一个或者零个参数,而且必须与属性的类型相同。参数为数据成员的新值。NOTIFY信号应该仅仅当属性值真正的发生改变时发出,以避免被QML重新评估。
(6)REVISION也是可选的,如果包含了该关键字,它定义了该属性和信号被特定版本的API使用通常是QML。如果没有包含该关键字其默认为0。
(7)DESIGNABLE指定了该属性在GUI编辑器中是否可见(比如QtDesigner)。大多数的属性是可设计的(DESIGNABLE默认为真)。除了true和false,你还可以指定boolean成员函数。
(8)SCRITABLE属性指定了该属性是否可以被script engine访问,其默认为真。除了true和false你还可以指定boolean函数。
(9)STORED属性指定了该属性是否是独立的或者是否依赖于别的属性。它也指定了当保存对象属性时是否会保存该属性。大多数的属性的STORED为真。但是,QWidget::minmunWidth()的STROED为false,因为它的值是从QQWidget::minimumSize()中取得的,它的类型是QSize。
(10)USER指定了属性是否被设计为用户可见和可编辑的。正常情况下,每一个对象只用一个USER属性(默认为false)。例如,QAbstractButton::clicked对Buttons是可编辑的(checkable)。注,QItemDelegate使用设置和访问函数色设置widget的USER属性。
(11)CONSTANT的出现表明属性是一个常量值。对于给点的对象实例,每一次READ函数的调用都应该返回相同的值。对于不同的实例该属性可能会不相同。同时不能有WRITE函数和NOTIFY信号。
(12)FINAL表明该属性不会再子类中被覆盖。在某些情况下它被用来优化性能,但是并没有被moc实现。必须注意,绝不在子类中覆盖FIANL属性。
(13)READ WRITE RESET函数可以被继承。它们也可以是虚函数。当在使用多继承的类中使用的时候,其必须来自第一个类。
3. 使用元对象系统读写属性
一个属性可以通过QObject::poperty()函数、QObject::setProperty()函数访问和设置。除了属性的名字之外不用知道类的别的信息。在下面的代码段中,调用函数QAbstractButton::setDown()和函数QObject::setProperty()都是设置属性“down”
QPushButton* button = new QPushButton;
QObject* object = button;
button->setDown(true);
object->setProperty("down" , true);
QObject *object = ...
const QMetaObject *metaObject = object->metaObject();
int count = metaObject->propertyCount();
for (int i = ; i< count; ++i) {
QMetaProperty metaProperty = metaObject->property(i);
cont char *name = metaProperty.name();
QVariant value = object->property(name);
}
class MyClass : public QObjct
{
Q_OBJECT
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
public:
explicit MyClass(QObject *parent = );
~MyClass(); enum Priority { High , Low , VeryHigh , VeryLow };
Q_ENUM(Priority) void setPriority(Priority priority)
{
m_priority = priority;
} Priority priority() const { return m_priority; } signals:
void priorityChanged(Priority); private:
Priority m_priority;
};
MyClass *myinstance = new MyClass;
QObject *object = myinstance; myinstance->setPriority(MyClass::VeryHigh);
object->setProperty("priority" , "VeryHigh");
4. 动态属性
QObject::setProperty()也可以被用来在运行时期为类实例添加属性。当传入名称和值调用该函数时。如果属性名称已经在类中存在并且传入的类型与属性的类型兼容,则属性值被保存并且返回真,否则值不会被修改,但是函数返回假。但是如果给定的属性名不存在则新的属性被添加到类中,当函数仍然返回false。这意味着函数的返回值不能用来确定属性值看是否被成功的设定。除非你已经知道属性之前是否存在。
附:所谓添加属性到QOject中二不是QMetaObject中的意思是:
假设:有两个MyClass对象的实例a 与 b,当为a动态添加一个属性时,b是不会受到影响的。
QMetaObject是所有的MyClass实例所共享的。
关于Q_DECLARE_METATYPE,另一个重要的用途就是用于注册信号和槽中使用的用户自定类型。
如果信号和槽使用Qt::QueuedConnection连接,则还需要使用qRegisterMetaType<T>()函数注册。
此外,Qt的状态机框架和动画框架依赖属性系统。
Qt属性系统(Qt Property System)的更多相关文章
- Qt 中的属性系统(Property System)
21 人赞同了该文章 本节内容主要讲解我对 Qt 属性系统的理解.官方文档参考 The Property System. 如何理解"属性系统"这个概念? 一般我们说一个类有什么属性 ...
- Qt属性系统
The Property System Qt提供一个类似于其他编译器供应商提供的精致的属性系统.然而,作为一个编译器和平台独立的库,Qt并不依赖于非标准编译器特性,如__property 或 [pro ...
- Qt之属性系统
简述 Qt提供一个类似于其它编译器供应商提供的复杂属性系统(Property System).然而,作为一个编译器和平台无关的库,Qt不能够依赖于那些非标准的编译器特性,比如:__property或者 ...
- Qt:Qt资源系统
学习自 Qt 资源系统(Qt Resource System) - 知乎 1.什么是Qt 资源系统 Qt资源系统是一种将图片.数据存储于二进制文件中的一套系统.这些图片.数据会被我们的程序使用,它们称 ...
- 深入了解Qt(二)之元对象系统(Meta-Object System)
深入了解Qt主要内容来源于Inside Qt系列,本文做了部分删改,以便于理解.在此向原作者表示感谢! 在Qt Meta Object System-元对象系统这篇文章中,从底层实现的源码剖析了元对象 ...
- Qt元对象和属性系统详解
Qt 是一个用标准 C++ 编写的跨平台开发类库,它对标准 C++ 进行了扩展,引入了元对象系统.信号与槽.属性等特性,使应用程序的开发变得更高效. 本节将介绍 Qt 的这些核心特点,对于理解和编写高 ...
- 解析Qt元对象系统(四) 属性系统(确实比较方便)
官方解释 我们在Qt源码中可以看到一个QObject的子类经常会用到一些Q_开头的宏,例如QMainWindow类开始部分代码是这样的: Q_PROPERTY(QSize iconSize READ ...
- QtCore是Qt的精髓(包括五大模块:元对象系统,属性系统,对象模型,对象树,信号槽)
作者:小豆君的干货铺链接:https://www.zhihu.com/question/27040542/answer/218384474来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业 ...
- Qt 属性
Qt提供了一套和一些编译器提供商也提供的属性系统类似的完善的属性系统.然而,作为一个不依赖编译器和平台的库,Qt不能依赖像__property或者[property]那样的非标准编译器特征.我们的 ...
随机推荐
- Android 开源项目精选
0x00 leakcanary [内存泄漏检测] Leakcanary : A memory leak detection library for Android and Java. 良心企业Squ ...
- 使用Excel2007去反复功能时要注意的一个问题
作者:iamlaosong Excel2007有个去反复功能(菜单:数据----删除反复项).非常实用,过去须要用VBA编程实现的功能,如今点击一下图标即可了.去反复通常是指定某列或者某几列.依据这指 ...
- linux下开启ftp的21号port
1.先执行vsftpd服务: #service vsftpd start 2.通过iptables开放21号port (1) 先查看iptables设置: #iptables -nL Chain IN ...
- JVM完全指南
JVM完全指南 一:虚拟机内存图解 JAVA程序运行与虚拟机之上,运行时需要内存空间.虚拟机执行JAVA程序的过程中会把它管理的内存划分为不同的数据区域方便管理. 虚拟机管理内存数 ...
- PowerBuilder -- 保存图片
String ls_path, ls_file_name, ls_filter, ls_errInt li_ret, li_loop, li_i, li_file, li_bytesLong ll_f ...
- UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position xxx ordinal not in range(12
python在安装时,默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报这样的错UnicodeDecodeError: 'ascii' codec can't deco ...
- oc中 中文到拼音的转换
偶然发现的一个好玩的功能
- 【BZOJ2406】矩阵 二分+有上下界的可行流
[BZOJ2406]矩阵 Description Input 第一行两个数n.m,表示矩阵的大小. 接下来n行,每行m列,描述矩阵A. 最后一行两个数L,R. Output 第一行,输出最小的答案: ...
- 兼容性强、简单、成熟、稳定的RTMPClient客户端拉流功能组件EasyRTMPClient
EasyRTMPClient EasyRTMPClient拉流功能组件是EasyDarwin流媒体团队开发.提供和维护的一套非常稳定.易用.支持重连的RTMPClient工具,SDK形式提供,全平台支 ...
- table表格隔行变色
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...