日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

The Property System

發(fā)布時(shí)間:2024/4/17 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 The Property System 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

感謝MaxValue,hennychen?對(duì)本文的翻譯,同時(shí)非常感謝Cxt_programmer在百忙中抽出時(shí)間對(duì)翻譯初稿的認(rèn)真校驗(yàn)。才使本文與讀者盡快見面。由于書稿內(nèi)容多,我們的知識(shí)有限,盡管我們進(jìn)行了細(xì)心的檢查,但是還是會(huì)存在錯(cuò)誤,這里懇請(qǐng)廣大讀者批評(píng)指正,并發(fā)送郵件至BeyondVincent@devdiv.com,在此我們表示衷心的感謝。

注:本文原文地址:The?Property?System。

?

????????????????????????????????????????第一章??????屬性系統(tǒng)

Qt提供了一個(gè)成熟的屬性系統(tǒng),它和某些編譯器廠商提供的屬性系統(tǒng)相似。但是,作為一個(gè)編譯器及平臺(tái)獨(dú)立的程序庫(kù),Qt并不依賴非標(biāo)準(zhǔn)的編譯器特性,如__property或[property]。Qt對(duì)屬性系統(tǒng)的解決方案可以在Qt支持的每一個(gè)平臺(tái)上的任何標(biāo)準(zhǔn)編譯器上工作,它是基于元對(duì)象系統(tǒng)(Meta-Object?System)的。對(duì)象間通信用的信號(hào)和槽機(jī)制也是基于元對(duì)象系統(tǒng)的。

?

?

?

?

?????????????????????????????????第二章??????定義屬性的要求

在繼承自QObject的類中使用Q_PROPERTY()宏定義屬性。

?

Q_PROPERTY(type name

??????????? READ getFunction

? ??????????[WRITE setFunction]

??????????? [RESET resetFunction]

??????????? [NOTIFY notifySignal]

??????????? [DESIGNABLE bool]

??????????? [SCRIPTABLE bool]

??????????? [STORED bool]

??????????? [USER bool]

??????????? [CONSTANT]

??????????? [FINAL])

?

在此,有幾個(gè)取自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)

雖然屬性的行為與類數(shù)據(jù)成員相似,但是,它具有額外的特性,這些特性可以通過元對(duì)象系統(tǒng)訪問。

n??READ?存取函數(shù)是必須的。它用于讀取屬性的值。原則上,這里使用const函數(shù),并且它必須返回屬性的類型、指針或者引用。例如,QWidget::focus?是與?READ函數(shù)QWidget::hasFocus()對(duì)應(yīng)的只讀屬性。

n??WRITE?存取函數(shù)是可選的。它用于設(shè)置屬性的值。它必須返回void并且?guī)б粋€(gè)參數(shù),這個(gè)參數(shù)可以是屬性的類型,指針,或者該類型的屬性。例如,QWidget::enabled?有WRITE?函數(shù)QWidget::setEnabled()。 只讀屬性不需要WRITE?函數(shù),如,QWidget::focus?就沒有WRITE函數(shù)。

n??RESET?函數(shù)是可選的。它用來將屬性設(shè)置回它的上下文指定的默認(rèn)值。如,QWidget::cursor?擁有典型的READ和WRITE?函數(shù):QWidget::cursor()?和?QWidget::setCursor()。同時(shí),還擁有RESET函數(shù)QWidget::unsetCursor(),如果沒有調(diào)用QWidget::setCursor(),該函數(shù)的作用就是重置為上下文指定的光標(biāo)。?RESET函數(shù)必須返回void,并且不帶參數(shù)。

n??NOTIFY?信號(hào)是可選的。 如果定義了,它應(yīng)該指定一個(gè)在那個(gè)類中存在的信號(hào),這個(gè)信號(hào)在屬性值改變時(shí)被發(fā)射。

n??DESIGNABLE 指明了該屬性是否對(duì)用戶界面設(shè)計(jì)工具(如,Qt Designer)的屬性編輯器可見。大多數(shù)屬性是DESIGNABLE的(默認(rèn)為true)。 除了true或false,你還可以指定一個(gè)boolean成員函數(shù)。

n??SCRIPTABLE 指明了該屬性是否能被腳本引擎訪問(默認(rèn)為true)。除了true或false,你還可以指定一個(gè)boolean成員函數(shù)。

n??STORED?指明了該屬性是否單獨(dú)存在或者依賴于其他值。 它同時(shí)也指明了當(dāng)存儲(chǔ)對(duì)象的狀態(tài)時(shí),屬性是否被保存。?大多數(shù)的屬性都是STORED的(默認(rèn)值為true),但是,QWidget::minimumWidth()的STORED值為false,因?yàn)樗闹祪H是取自寬度組件屬性QWidget::minimumSize(),它的值是一個(gè)QSize

n??USER?指明了類中該屬性是否被指定為面向用戶的或者用戶可編輯的。通常情況下,每個(gè)類中僅有一個(gè)USER屬性(其默認(rèn)值為false),如QAbstractButton::checked即為(可復(fù)選)按鈕的用戶可編輯屬性。注意,QItemDelegate能獲取和設(shè)置組件的 USER屬性。

n??CONSTANT的存在,表明該屬性是常量。 對(duì)于給定的對(duì)象實(shí)例,常量屬性的READ方法每次調(diào)用的時(shí)候必須返回相同的值。 該常量的值,對(duì)于不同的對(duì)象實(shí)例可能是不同的。?常量屬性不能有WRITE方法或者NOTIFY信號(hào)。

n??FINAL的存在,表明該屬性不能被子類覆蓋。 這可以用于某些類中的性能優(yōu)化,但是,并不是由moc強(qiáng)制執(zhí)行的。 一定要注意,絕對(duì)不要覆蓋FINAL屬性。

READ, WRITE,?和RESET函數(shù)可以被繼承。 它們也可以是virtual的。 當(dāng)它們以多繼承的方式被繼承時(shí),它們必須是來自第一個(gè)被繼承的類。

屬性的類型可以是任何被QVariant支持的類型,或者是用戶自定義的類型。 下面的例子中,QDate類被視為用戶自定義類型。

?

Q_PROPERTY(QDate date READ getDate WRITE setDate)

?

由于QDate是用戶自定義的,所以,你在屬性聲明時(shí)必須包含<QDate>頭文件。

對(duì)于QMap,?QList,和QValueList屬性,屬性值是QVariant類型的,它的值是整個(gè)list或者map。注意Q_PROPERTY中不包含逗號(hào),因?yàn)槎禾?hào)會(huì)分隔宏參數(shù)。因此,你一定要使用QMap作為屬性類型,而不是QMap<QString,QVariant>。 為了保持一致性,同樣應(yīng)該使用QList和 QValueList,而不是QList<QVariant>?和?QValueList<QVariant>。

?

?

?

?

???????????????????????第三章??????使用元對(duì)象系統(tǒng)讀寫屬性

屬性可以通過通用函數(shù)QObject::property()和QObject::setProperty()來讀寫,此時(shí),除了屬性的名稱,不需要了解所擁有類的其他情況。下面的代碼片段中,對(duì)QAbstractButton::setDown()的調(diào)用,和對(duì)QObject::setProperty()都是對(duì)“down”屬性的設(shè)置。

?QPushButton *button = new QPushButton;

?QObject *object = button;

?

?button->setDown(true);

?object->setProperty("down", true);

通過?WRITE存取函數(shù)訪問屬性是上面兩種方式中較好的,因?yàn)樗咝?#xff0c;并且在編譯時(shí)會(huì)給出更多的診斷提示。但是,以該方式設(shè)置屬性需要你在編譯時(shí)就知道這個(gè)類的定義。通過名稱訪問屬性時(shí),不需要知道類的定義。你可以在運(yùn)行時(shí),通過QObject,?QMetaObject,和?QMetaProperties去查詢類的屬性。

?QObject *object = ...

?const QMetaObject *metaobject = object->metaObject();

?int count = metaobject->propertyCount();

?for (int i=0; i<count; ++i) {

???? QMetaProperty metaproperty = metaobject->property(i);

???? const char *name = metaproperty.name();

???? QVariant value = object->property(name);

???? ...

?}

上面的代碼片段中,QMetaObject::property()用于獲取定義在某些未知類中與每個(gè)屬性相關(guān)的metadata。 屬性名稱取自metadata,并且傳給QObject::property(),用于獲取在當(dāng)前object中屬性的value

?

?

?

???????????????????????????????????第四章??????一個(gè)簡(jiǎn)單例子

假設(shè)我們有一個(gè)MyClass類,它繼承自QObject,并且在private域中使用了Q_OBJECT宏。我們要在MyClass中聲明一個(gè)屬性用于保存優(yōu)先級(jí)(priority value)。 屬性的名稱將是priority,它的類型是MyClass中定義的一個(gè)枚舉類型Priority。

我們?cè)陬惖膒rivate域中用Q_PROPERTY()宏聲明屬性。 所需的 READ 函數(shù)被命名為這里,這里包括一個(gè)名為 setPriority 的WRITE函數(shù)。 枚舉類型必須與使用 Q_ENUMS()注冊(cè)到元對(duì)象系統(tǒng)。 注冊(cè)一個(gè)枚舉類型使枚舉名在調(diào)用QObject::setProperty()時(shí)使用。我們還必須提供自己的讀取和寫入函數(shù)的聲明。MyClass的聲明如下所示:

class MyClass : public QObject

?{

???? Q_OBJECT

???? Q_PROPERTY(Priority priority READ priority WRITE setPriority)

???? Q_ENUMS(Priority)

?

?public:

???? MyClass(QObject *parent = 0);

???? ~MyClass();

?

???? enum Priority { High, Low, VeryHigh, VeryLow };

?

???? void setPriority(Priority priority);

???? Priority priority() const;

?};

?

?? ??READ函數(shù)是const函數(shù),并返回屬性類型。 WRITE函數(shù)返回 void,并且以屬性類型作為參數(shù)。 元對(duì)象編譯器強(qiáng)制執(zhí)行這些規(guī)定。

我們有兩種方法設(shè)置其priority屬性,一個(gè)指向MyClass實(shí)例的MyClass *或者一個(gè)指向MyClass實(shí)例的QObject *:

MyClass *myinstance = new MyClass;

QObject *object = myinstance;

?

myinstance->setPriority(MyClass::VeryHigh);

object->setProperty("priority", "VeryHigh");

在這個(gè)例子中,屬性類型的枚舉在MyClass類中聲明,并使用 Q_ENUMS() 宏注冊(cè)到元對(duì)象系統(tǒng)。這使得調(diào)用setProperty()時(shí),枚舉值可作為字符串形式傳入。在另一個(gè)類中定義的枚舉類型,需要完整的名稱,如:(i.e., OtherClass::Priority), 且該類也必須繼承QObject 并使用 Q_ENUMS()宏注冊(cè)該枚舉類型。

Q_FLAGS()宏也可以提供類似的功能。 和Q_ENUMS()類似,在注冊(cè)一個(gè)枚舉類型的同時(shí),會(huì)將該類型標(biāo)注為一組標(biāo)記。例如,可以使用或運(yùn)算合并各個(gè)標(biāo)記。一個(gè)I/O類可能有Read和Write枚舉值,并且QObject::setProperty()可以接受Read |Write這樣的‘或’方式,此時(shí)應(yīng)該使用Q_FLAGS()注冊(cè)這個(gè)枚舉類型。

第五章??????動(dòng)態(tài)的屬性(Properties)

QObject::setProperty() 還可以在運(yùn)行時(shí)將新屬性添加到對(duì)象中。調(diào)用QObject::setProperty() 時(shí)傳入屬性名和屬性值,如果該屬性存在于QObject中,并且屬性值與屬性類型相匹配的話,屬性值將被存儲(chǔ)到屬性中,setProperty返回 true。如果屬性類型與屬性值不匹配,屬性將不會(huì)改變,setProperty返回false。但是,如果QObject中沒有給定名稱的屬性(即,如 果這個(gè)屬性沒用Q_PROPERTY()聲明,則新屬性和屬性值自動(dòng)添加到該的 QObject,但setProperty仍返回 false。這意味著不能從setProperty返回fasle來判斷屬性是否被正確設(shè)置,除非你預(yù)先知道QObject中已經(jīng)有該屬性。

請(qǐng)注意動(dòng)態(tài)屬性的添加基于每個(gè)實(shí)例,它們會(huì)添加到 Qobject中,而不是 QMetaObject。調(diào)用QObject::setProperty()時(shí)傳遞一個(gè)屬性名和一個(gè)無效的QVariant,可以從實(shí)例中刪除該屬性。

?QVariant 的默認(rèn)構(gòu)造函數(shù)構(gòu)造一個(gè)無效的 QVariant。

如同使用Q_PROPERTY().在編譯時(shí)聲明屬性,動(dòng)態(tài)屬性可以用QObject::property()查詢。

?

????????????第六章??????屬性(Properties)和自定義類型

使用屬性的自定義類型需要使用 Q_DECLARE_METATYPE() 宏注冊(cè),以便可以在 QVariant 對(duì)象中存儲(chǔ)它們的值。這使他們既適合使用 Q_PROPERTY() 宏在類定義中聲明靜態(tài)屬性,又適合在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建屬性。

?

??????????????????????????????第七章??????給類添加附屬信息

Q_CLASSINFO()宏可以連接到屬性系統(tǒng),為類的meta-object添加一對(duì)name-value,例如:

Q_CLASSINFO("Version", "3.0.0")

?

與其他原數(shù)據(jù)(meta-data)一樣,類信息可以在運(yùn)行時(shí)通過meta-object訪問,請(qǐng)參閱 QMetaObject::classInfo()。

另請(qǐng)參閱元對(duì)象系統(tǒng)(Meta-Object?System)、 信號(hào)和槽(Signals and Slots)、Q_DECLARE_METATYPE()、QMetaTypeQVariant

轉(zhuǎn)載于:https://www.cnblogs.com/senior-engineer/p/11155989.html

與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的The Property System的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。