Qt提供了一套和一些编译器提供商也提供的属性系统类似的完善的属性系统。然而,作为一个不依赖编译器和平台的库,Qt不能依赖像__property或者[property]那样的非标准编译器特征。我们的解决方案可以在我们支持的每一个平台上和任何标准的C++编译器一起工作。它基于元对象系统,元对象系统也通过信号和槽提供对象通讯。
在类声明中的Q_PROPERTY宏声明了一个属性。属性只能在继承于QObject的子类中声明。第二个宏,Q_OVERRIDE,可以用来覆盖一些子类中由继承得到的属性。
对于外面的世界,属性看起来和一个数据成员非常类似。然而,属性和普通的数据成员还是有一下一些不同点:
 
  • 一个读函数。这是一直存在的。

     
  • 一个写函数。这个是可选的:像QWidget::isDesktop()这样的只读的属性就没有写函数。
     
  • “存储”特征需要说明持续性。绝大多数属性是被存储的,但是有一小部分的虚拟属性却不用。举个例子,QWidget::minimumWidth()是不用存储的,因为它只是QWidget::minimumSize()的一种查看,没有自己的数据。
     
  • 一个复位函数用来把属性设置回它根据上下文的特定缺省值。这个用法还是比较罕见的,但是举个例子,QWidget::font()需要这个函数,因为没有调用QWidget::setFont()意味着“复位到根据上下文特定的字体”。
     
  • “可设计”特征说明它是否可以被一个图形用户界面生成器(例如Qt设计器)设置属性。对于大多数属性都有这个特征,但不是所有,例如QButton::isDown()。用户可以按按钮,并且应用程序设计人员可以让程序来按它自己的按钮,但是一个图形用户界面设计工具不能按按钮。
     
读、写和复位函数就像任何成员函数一样,继承或不继承,虚或不虚。只有一个例外就是,在多重继承的情况下,成员函数必须从第一个被继承类继承。
属性可以在不知道被使用的类的任何情况的时候通过QObject中的一般函数进行读写。下面两个函数调用是等效的:
 
    // QButton *b和QObject *o指向同一个按钮
b->setDown( TRUE );
o->setProperty( "down", TRUE );
等效的是指,除了第一个函数要快一些,在编译的时候提供了更好的诊断信息。在实际应用中,第一个函数更好些。然而,因为我们可以通过QMetaObject获得任何一个QObject的所有有用属性的一个列表,QObject::setProperty()可以让你控制类中那些在编译时不可用的属性。
QObject::setProperty()一样,还有一个相应的QObject::property()函数。QMetaObject::propertyNames()返回所有可用属性的名称。QMetaObject::property()返回一个指定属性的属性数据:一个QMetaProperty对象。
这里有一个简单的例子说明了可以应用的绝大多数重要属性函数:
 
    class MyClass : public QObject
{
Q_OBJECT
public:
MyClass( QObject * parent=0, const char * name=0 );
~MyClass(); enum Priority { High, Low, VeryHigh, VeryLow };
void setPriority( Priority );
Priority priority() const;
};
这个类有一个名为“priority”的还不被元对象系统所知的属性。为了让这个属性被元对象系统知道,你必须用Q_PROPERTY宏来声明它。声明语法如下:
 
Q_PROPERTY( type name READ getFunction [WRITE setFunction]
[RESET resetFunction] [DESIGNABLE bool]
[SCRIPTABLE bool] [STORED bool] )
为了声明是有效的,读函数必须是常量函数并且返回值的类型是它本身或者是指向它的指针,或者是它的一个引用。可选的写函数必须返回void并且必须带有一个正确的参数,类型必须是它本身或者是指向它的指针,或者是它的一个常量引用。元对象编译器强迫这样的。
属性的类型可以是任何一个QVariant支持的类型或者是一个自己在类中已经定义的枚举类型。因为MyClass中的属性使用了枚举类型Priority,这个类型必须也向属性系统注册。这样的话,像如下方式通过名称来设置值是可行的:
 
    obj->setProperty( "priority", "VeryHigh" );
枚举类型必须使用Q_ENUMS宏来进行注册。这里是一个包含属性相关声明的最终的类声明:
 
    class MyClass : public QObject
{
Q_OBJECT
Q_PROPERTY( Priority priority READ priority WRITE setPriority )
Q_ENUMS( Priority )
public:
MyClass( QObject * parent=0, const char * name=0 );
~MyClass(); enum Priority { High, Low, VeryHigh, VeryLow };
void setPriority( Priority );
Priority priority() const;
};
另外一个类似的宏是Q_SETS。像Q_ENUMS一样,它注册了一个枚举类型,但是它额外的加了一个“set”的标记,也就是说,这个枚举数据可以被一起读或写。一个输入输出类也许有枚举数据“读”和“写”和接收“读|写”:这时最好用Q_SETS来声明一个枚举类型,而不是Q_ENUMS
Q_PROPERTY段剩余的关键字是RESETDESIGNABLESCRIPTABLE和STORED。
RESET指定一个函数可以设置属性到缺省状态(这个缺省状态可能和初始状态不同)。这个函数必须返回void并且不带有参数。
DESIGNABLE声明这个属性是否适合被一个图形用户界名设计工具修改。缺省的TRUE是说这个属性可写,否则就是FALSE说明不能。你可以定义一个布尔成员函数来替代TRUEFALSE
SCRIPTABLE声明这个属性是否适合被一个脚本引擎访问。缺省是TRUE,可以。你可以定义一个布尔成员函数来替代TRUEFALSE
STORED声明这个属性的值是否必须作为一个存储的对象状态而被记得。STORED只对可写的属性有意义。缺省是TRUE。技术上多余的属性(比如,如果QRect的geometry已经是一个属性了的QPoint的pos)定义为FALSE
连接到属性系统是一个附加宏,“Q_CLASSINFO”,它可以用来把名称/值这样一套的属性添加到一个类的元对象中,例如:
 
    Q_CLASSINFO( "Version", "3.0.0" )
和其它元数据一样,类信息在运行时是可以通过元对象访问的,具体请看QMetaObject::classInfo()。

Qt 属性的更多相关文章

  1. Qt属性系统(Qt Property System)

    Qt提供了巧妙的属性系统,它与某些编译器支持的属性系统相似.然而,作为平台和编译器无关的库,Qt不能够依赖于那些非标准的编译器特性,比如__property 或者 [property].Qt的解决方案 ...

  2. Qt属性表控件的使用 QtTreePropertyBrowser

    属性表是vs2003时引入的的新控件,用于流量和设置大量的信息,现在,很多软件上都能看到它的身影,如vs,Qt Creator等IDE的详细设置里都离不开属性表. 下图是Qt Creator里的属性表 ...

  3. Qt属性系统

    The Property System Qt提供一个类似于其他编译器供应商提供的精致的属性系统.然而,作为一个编译器和平台独立的库,Qt并不依赖于非标准编译器特性,如__property 或 [pro ...

  4. Qt之属性系统

    简述 Qt提供一个类似于其它编译器供应商提供的复杂属性系统(Property System).然而,作为一个编译器和平台无关的库,Qt不能够依赖于那些非标准的编译器特性,比如:__property或者 ...

  5. Qt之QSS(Q_PROPERTY-原始属性)

    http://blog.csdn.net/liang19890820/article/details/51698536 版权声明:进步始于交流,收获源于分享!纯正开源之美,有趣.好玩.靠谱...作者: ...

  6. 解析Qt元对象系统(四) 属性系统(确实比较方便)

    官方解释 我们在Qt源码中可以看到一个QObject的子类经常会用到一些Q_开头的宏,例如QMainWindow类开始部分代码是这样的: Q_PROPERTY(QSize iconSize READ ...

  7. PyQt(Python+Qt)学习随笔:Qt Designer中部件的样式表styleSheet属性

    styleSheet属性是定义部件外观的属性样式表,在Qt中styleSheet样式表是类似于html的css样式一样的方法,只是时专门为Qt中的部件开发的.styleSheet的定义语法也是类似CS ...

  8. PyQt(Python+Qt)入门:Designer组件属性编辑界面中QWidget类相关属性详解

    本文适用人员:本文比较长,适合不理解Qt Designer部件属性的人员阅读或资料查找. 声明: 1.如果有人认为本文是简单的复制粘贴+翻译而成,敬请读本文最后的后记: 2.本文为老猿Python学习 ...

  9. Qt 中的属性系统(Property System)

    21 人赞同了该文章 本节内容主要讲解我对 Qt 属性系统的理解.官方文档参考 The Property System. 如何理解"属性系统"这个概念? 一般我们说一个类有什么属性 ...

随机推荐

  1. HTML5 表单与文件

    -新增元素与属性 form.formaction.formmethod.placeholder(处于未输入状态时文本框显示的输入提示).autofocus(自动获取光标焦点).list(该属性的值为某 ...

  2. linux下svn客户端报错Cannot negotiate authentication mechanism的解决方法

    svn客户端报错Cannot negotiate authentication mechanism的解决方法: 问题出现的原因之一: 因为SVN服务器配置了saslauthd服务用来实现与ldap的对 ...

  3. PM加油站

    老郭讲述深航CSM 1.需求有遗漏,人员水平不足:加班导致人员流失:但是这样,客户后来还是好评,并且项目被评为深航的标杆项目:老郭也是被指定为未来项目的项目经理:--!我想起了古时候的一句话:功夫在诗 ...

  4. bzoj2395: [Balkan 2011]Timeismoney

    Description      有n个城市(编号从0..n-1),m条公路(双向的),从中选择n-1条边,使得任意的两个城市能够连通,一条边需要的c的费用和t的时间,定义一个方案的权值v=n-1条边 ...

  5. 关于html5

    html5   是用来  将 js  和 css  结合起来 从而实现 各种功能 javascript 用来定义 html5   页面的逻辑 css 来定义 html5 中的显示样式

  6. win32控制台实现按任意键退出的功能

    win7之后的五win32 控制台出现了程序运行完之后就立即结束的问题,程序员根本无法看输出的结果.未来让控制台运行完之后能够等待程序员的操作.可以使用: system("PAUSE&quo ...

  7. Oracle问题解决(sqlplus无法登陆)

    命令行 sqlplus 无法登陆,常常是用户名/密码错误.监听配置错误或未启动.数据库服务名丢失等等原因. 用户名/密码错误 找到自己设的密码 这全靠自己创建数据库实例时,备份或记住相关信息 若最后没 ...

  8. frameset iframe用来分页

    frameset用来分大的框架 iframe用来在frame分框架之后,内嵌分割. <FRAMESET border=1 frameSpacing=1 borderColor=#47478d r ...

  9. sql restore mode

    refer : https://msdn.microsoft.com/en-us/library/ms189272.aspx SELECT name, recovery_model_desc FROM ...

  10. OTP语音芯片和掩模语音芯片(mask)的区别

    OTP(One Time Programable)是MCU的一种存储器类型,意思是一次性可编程:程序烧入IC后,将不可再次更改和:因此OTP语音芯片就是指一次性烧录的语音IC. 从OTP定义上来看,只 ...