Qt属性系统(QtPropertySystem)
Qt提供了巧妙的属性系统,它与某些编译器支持的属性系统相似。然而,作为平台和编译器无关的库,Qt不能够依赖于那些非标准的编译器特性,比如property或者〔property〕。Qt的解决方案能够被任何Qt支持的平台下的标准C编译器支持。它依赖于元对象系统(MetaObjectSytstem),元对象系统通过信号和槽提供了对象间通讯的机制。1。Qt中怎么声明属性?
QObject中的子类的私有域中使用QPROPERTY宏来声明一个属性
以下是来自QWidget类的一些属性声明QPROPERTY(boolfocusREADhasFocus)QPROPERTY(boolenabledREADisEnabledWRITEsetEnabled)QPROPERTY(QCursorcursorREADcursorWRITEsetCursorRESETunsetCursor)以下例子展示了如何使用MEMBER关键字将类数据成员导出为Qt属性。注,NOTIFYsignal必须被指定,这样才能被QML使用QPROPERTY(QColorcolorMEMBERmcolorNOTIFYcolorChanged)QPROPERTY(qrealspaingMEMBERmspacingNOTIFYspaingChanged)QPROPERTY(QStringtextMEMBERmtextNOTIFYtextChanged)。。。signals:voidcolorChanged();voidspacingChanged();voidtextChanged(constQStringnetText);private:QColormcolor;qrealmspacing;QStringmtext;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属性指定了该属性是否可以被scriptengine访问,其默认为真。除了true和false你还可以指定boolean函数。
(9)STORED属性指定了该属性是否是独立的或者是否依赖于别的属性。它也指定了当保存对象属性时是否会保存该属性。大多数的属性的STORED为真。但是,QWidget::minmunWidth()的STROED为false,因为它的值是从QQWidget::minimumSize()中取得的,它的类型是QSize。
点击领取Qt学习资料视频教程
链接
(10)USER指定了属性是否被设计为用户可见和可编辑的。正常情况下,每一个对象只用一个USER属性(默认为false)。例如,QAbstractButton::clicked对Buttons是可编辑的(checkable)。注,QItemDelegate使用设置和访问函数色设置widget的USER属性。
(11)CONSTANT的出现表明属性是一个常量值。对于给点的对象实例,每一次READ函数的调用都应该返回相同的值。对于不同的实例该属性可能会不相同。同时不能有WRITE函数和NOTIFY信号。
(12)FINAL表明该属性不会再子类中被覆盖。在某些情况下它被用来优化性能,但是并没有被moc实现。必须注意,绝不在子类中覆盖FIANL属性。
(13)READWRITERESET函数可以被继承。它们也可以是虚函数。当在使用多继承的类中使用的时候,其必须来自第一个类。
属性类型可以是任何QVariant支持的属性,或者是用户自定义的属性。在这个例子中,类QDate被看做用户自定义的类型。QPROPERTY(QDatedataREADgetDateWRITEsetDate)因为QDate是用户自定义的,当声明属性时,你必须包含头文件。由于历史原因,QMap和QList是QVariantMap和QVariantList的同义词。3。使用元对象系统读写属性
一个属性可以通过QObject::poperty()函数、QObject::setProperty()函数访问和设置。除了属性的名字之外不用知道类的别的信息。在下面的代码段中,调用函数QAbstractButton::setDown()和函数QObject::setProperty()都是设置属性downQPushButtonbuttonnewQPushButton;QObjectobjectbutton;buttonsetDown(true);objectsetProperty(down,true);
通过WRITE函数设置属性值,比上述两者都好,因为它效率更高而且在编译时期有更好的诊断。但是这需要你在编译实际了解整个类(能够访问其定义)。通过属性名访问属性,能够让你再不了解类的定义的情况访问或者设置属性。你可以在运行时期通过QObject,QMetaObject和QMetaProperties查询类属性。QObjectobject。。。constQMetaObjectmetaObjectobjectmetaObject();intcountmetaObjectpropertyCount();for(inti0;icount;i){QMetaPropertymetaPropertymetaObjectproperty(i);contcharnamemetaProperty。name();QVariantvalueobjectproperty(name);}
在上述的代码片段中,QMetaObject::property()被用来获取定义在某个未知的类中的metaData。属性的名称通过metaData获取,并且将其传给QObject::property()来获取属性值。
假设我们有一个简单的类MyClass,它继承自QObject而且在private域中使用了QOBJECT。我们想声明一个属性用于跟踪权限值。该属性的名称是priority,它的类型是定义在MyClass中的Priority枚举。
点击领取Qt学习资料视频教程
链接
我们使用QPROPERTY在private区里声明属性。READ函数是priority(),WRITE函数是setPriority()。枚举类型需要使用QENUM()宏将其注册到MetaObjectSystem中。注册一个枚举类型使得枚举可以在setPropert函数中使用。我们也必须提供READ和WRITE函数的声明。该类的定义如下:classMyClass:publicQObjct{QOBJECTQPROPERTY(PrioritypriorityREADpriorityWRITEsetPriorityNOTIFYpriorityChanged)public:explicitMyClass(QObjectparent0);MyClass();enumPriority{High,Low,VeryHigh,VeryLow};QENUM(Priority)voidsetPriority(Prioritypriority){mprioritypriority;}Prioritypriority()const{returnmpriority;}signals:voidpriorityChanged(Priority);private:Prioritympriority;};
READ函数是常成员函数而且返回Priority类型。WRITE函数返回void而且只有一个类型为Priority的参数。
给定一个指向MyClass实例的类型为MyClass或者QObject的指针,我们有两种方式去设置它的priority属性。MyClassmyinstancenewMyClass;QObjectobjectmyinstance;myinstancesetPriority(MyClass::VeryHigh);objectsetProperty(priority,VeryHigh);
在这个例子中,定义在MyClass中的枚举类型是属性的类型,而且被QENUM()宏注册在MetaObjectSystem中。这使得枚举类型可以在setProperty中通过字符串访问(string),使用在别的类中定义的枚举类型,他必须被完全的声明(i。e。OtherClass::Priority)。而且那个类应该继承自QObject而且使用QENUM()宏注册。
一个相似的宏QFLAG()。就像QENUM()一样,它注册枚举类型,但是将其标记为一系列的flag,即,可以使用或操作。一个IO类有着Read和Write的枚举值,而且之后可以在QObject::setProperty传入ReadWrite访问。QFLAG()应该被用来注册枚举类型。4。动态属性
QObject::setProperty()也可以被用来在运行时期为类实例添加属性。当传入名称和值调用该函数时。如果属性名称已经在类中存在并且传入的类型与属性的类型兼容,则属性值被保存并且返回真,否则值不会被修改,但是函数返回假。但是如果给定的属性名不存在则新的属性被添加到类中,当函数仍然返回false。这意味着函数的返回值不能用来确定属性值看是否被成功的设定。除非你已经知道属性之前是否存在。
注:动态属性被添加到每一个实例中。即它们被添加到QObject中而不是QMetaObject中。可以通过传递一个空的QVariant给setProperty函数来移除属性。QVariant的默认构造函数构造一个无效的QVariant对象。
动态属性可以通过QObject::property()查询,就像QPROPERTY定义的属性一样。
被属性使用的自定义类型需要使用QDECLAREMETATYPE宏注册。这样QVariant对象才能够保存该类的值。这个在动态和静态属性都是适用的。
点击领取Qt学习资料视频教程
链接
为类添加额外的信息与属性系统相对应的是QCLASSINFO(name,value)宏。这个宏将添加namevalue的到类的元对象中。例如:
QCLASSINFO(Version,3。0。0)
和被使用的元对象数据一样,类信息可以在运行时通过QMetaObject::classInfo函数访问。附:所谓添加属性到QOject中二不是QMetaObject中的意思是:假设:有两个MyClass对象的实例a与b,当为a动态添加一个属性时,b是不会受到影响的。QMetaObject是所有的MyClass实例所共享的。关于QDECLAREMETATYPE,另一个重要的用途就是用于注册信号和槽中使用的用户自定类型。如果信号和槽使用Qt::QueuedConnection连接,则还需要使用qRegisterMetaTypeT()函数注册。此外,Qt的状态机框架和动画框架依赖属性系统。
小个子女生适合什么发型?蓬松随意效果都说每个人的发型非常重要,很多人都很喜欢更换发型,一款适合自己的发型会为自己的颜值气质加分不少,小个子女生很多,那么小个子女生适合什么发型?蓬松随意效果。小个子女生适合什么发型……
盈利双降,东风集团转型的路该如何走?当东风发布财报后,外界才对其3月一系列动作的原因,有了才较为具体的感知。近日,东风集团发布2022年度财报,财报内容显示,去年东风集团营收926亿元,与2021年相比,下……
美国科技巨头业绩集体受挫断臂之余寻路创新增长点美国科技巨头的低迷境况还在持续。近日,美国科技巨头密集发布了2022年第四季度财报。从财报数字来看,企业净利润大幅下跌、业绩整体滑坡成为关键词。其中,Meta公司2……
paese粉底液适合哪种肤质paese粉底液好用吗paese粉底液还是挺火的,这款粉底液的瓶身不大,但是能使用很长时间,那么paese粉底液适合哪种肤质呢,paese粉底液怎么样呢。paese粉底液适合哪种肤质Paese……
护发素不洗掉会怎样?护发素几分钟洗掉?洗发水用之后用护发素,现在是人们的常识,护发素的使用能让头发顺滑不打结,容易梳理,下面5号网小编带大家来看一下护发素不洗掉会怎样?护发素几分钟洗掉?护发素不洗掉会怎样很多……
2018世界杯美甲图片大全世界杯美甲图案款式美甲是很多女性朋友都非常喜欢的一件事情,美甲的款式多种多样,很多朋友都会经常更换美甲款式,2018年世界杯正在如火如荼的举行着,那么下面就由5号网的小编为大家带来2018世界杯……
不吃早餐能瘦身?揭秘最新健康养生法!近年来,越来越多的人开始关注养生和健康饮食,而不吃早餐成为了一种新兴的减肥方法。许多人认为不吃早餐能够有效地瘦身,但是这种做法真的健康吗?首先,不吃早餐可能会让你感到疲劳……
父亲和母亲寄往天堂的诗张文木一hr父亲,父亲,我小时见你有几次酩酊大醉!为什么喝酒?到你当时的年龄,我才知道你有很多无奈:大局,大局!有了……
如何让底妆更紧致呢小编教你妙招底妆在化妆环节中非常重要,底妆画的好,妆成一半,如何才能让底妆变得更紧致呢?下面小编来教你妙招!底妆紧致小技巧Tips1:粉底刷和手指并用面部有很多细节的地方,像鼻翼两侧……
美国机场模拟器Steam页面上线支持简中今日(4月6日),模拟经营游戏《美国机场模拟器》Steam页面上线,游戏支持简体中文,发售日期待定,感兴趣的玩家可以进入商店页面。游戏介绍:这是接近90年代后期的阿……
拍证件照怎么化妆好看最美证件照妆容教程前些天正好有拍摄证件照的需要,所以下了班就开始捣鼓自己。当时为了图快,也没有挑选很多彩妆产品。心想着只要有眉毛,有气色,不是素颜上镜就好了。这么一画,我就想到了还是有很多小仙女……
新疆是个好地方图文清风新疆是个好地方,那是来自于王洛宾的歌声里,这印象一直在我心里停留,特别是近年流行王棋的那首《可可托海牧羊人》和《那拉提养蜂女》,简直听的人如醉如痴。所以,一直有个……