Qt屬性系統

2022-01-12 16:41:44 字數 3656 閱讀 5144

qt提供了一套和其他通用編譯器提供商所提供的屬性系統類似的屬性系統 ,然而,作為乙個獨立於編譯器和平台的庫,qt不能依賴像__property或者[property]那樣的非標準編譯器特徵。qt的解決方案是在支援任意標準平台上的c++編譯器的基礎上進行工作。它基於元物件系統,元物件系統也通過訊號和槽提供物件通訊。

一、宣告屬性

1、要求

2)必須整合qobject()。

2、屬性類別

read getfunction

[write setfunction]

[reset resetfunction]

[notify notifysignal]

[revision int]

[designable bool]

[scriptable bool]

[stored bool]

[user bool]

[constant]

[final])

1)read getfunction

必須有的,用於讀取屬性,使用const限定,返回屬性的型別或者型別的指標或引用。

2)write setfunction

可選的,用於設定屬性,引數是乙個屬性的型別,或者屬性的const指標或引用,返回值是void。

3)reset resetfunction

可選的,用於把屬性根據上下文設定回它的特定預設值,沒有引數,返回void。

4)notify notifysignal

可選的,當屬性改變時發射的訊號。

5)revision int

可選的,定義屬性和它的訊號暴露給qml的修訂版本。

6)designable bool

該屬性是否在qt的qtdesigner設計器中顯示,預設true即為顯示。

7)scriptable bool

該屬性是否可以通過指令碼系統進行訪問,預設true即為可訪問。

8)stored bool

9)user bool

user變數表明屬性是否被設計為面向使用者的或使用者可修改的類屬性。通常,每個類只有乙個user屬性。例如,qabstractbutton::checked是按鈕類的使用者可修改屬性。

10)constant

constant的出現表明屬性的值是不變的。對於乙個object例項,常量屬性的read方法在每次被呼叫時必須返回相同的值。此常量值可能在不同的object例項中不相同。乙個常量屬性不能具有write方法或noyify訊號。

11)final

final變數的出現表明屬性不能被派生類所重寫。有些情況下,這可以用於效率優化,但不是被moc強制的。程式設計師必須永遠注意不能重寫乙個final屬性。

read,write和reset函式都可以被繼承。它們也可以是虛函式。當它們在被多重繼承中被繼承時,它們必須出現在第乙個被繼承的類中。

3、型別的種類

屬性的型別可以是被qvariant支援的所有型別,也可以是使用者定義的型別。自定義型別需要使用q_declare_metatype()巨集註冊,以使它們的值能被儲存在qvariant物件中。

對於qmap,qlist和qvaluelist屬性,屬性的值是乙個qvariant,它包含整個list或map。注意q_property字串不能包含逗號,因為逗號會劃分巨集的引數。因此,你必須使用qmap作為屬性的型別而不是qmap。為了保持一致性,也需要用qlist和qvaluelist而不是qlist和qvaluelist。

4、屬性讀寫方式

乙個屬性可以使用常規函式qobject::property()和qobject::setproperty()進行讀寫,不用知道屬性所在類的任何細節,除了屬性的名字。在下面的小**片段中,呼叫qabstractbutton::setdown()和qobject::setproperty()都把屬性設定為「down」。

qpushbutton *button = new qpushbutton;  

qobject *object = button;  

button->setdown(true);  

object->setproperty("down", true);  

通過write操作器來操作乙個屬性是上面兩者中更好的,因為它快並且在編譯時給於更好的診斷幫助,但是以這種方式設定屬性要求你必須在編譯時了解其類。通過名字來操作屬性使你可以操作在編譯器你不了解的類。你可以在執行時發現乙個類的屬性們,通過查詢它的qobject,qmetaobject和qmetaproerties。

qobject *object = ...  

const qmetaobject *metaobject = object->metaobject();  

int count = metaobject->propertycount();  

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

void setpriority(priority priority);  

priority priority() const;  

read函式是const的並且返回屬性的型別。write函式返回void並且具有乙個屬性型別的引數。元資料物件編譯器強制做這些事情。

在有了乙個指向myclass例項的指標時,我們有兩種方法來設定priority屬性:

myclass *myinstance = new myclass;  

qobject *object = myinstance;  

myinstance->setpriority(myclass::veryhigh);  

object->setproperty("priority", "veryhigh");  

在此例子中,列舉型別在myclass中宣告並被使用q_enums()註冊到元資料物件系統中。這使得列舉值可以在呼叫setproperty()時做為字串使用。如果列舉型別是在其它類中宣告的,那麼我們就需要用列舉的全名(如otherclass::priority),並且這個其它類也必須從qobject中派生並且也要註冊列舉型別。

另乙個簡單的q_flags()也是可用的。就像q_enums(),它註冊乙個列舉型別,但是它把列舉型別作為乙個flag的集合,也就是,值可以用or操作來合併。乙個i/o類可能具有列舉值read和write並且qobject::setproperty()可以接受 read|write。此時應使用q_flags()來註冊列舉值。

6、動態屬性

qobject::setproperty()也可以用來在執行時向乙個類的例項新增新的屬性。當使用乙個名字和值呼叫它時,如果乙個對應的屬性已經存在,並且如果值的型別與屬性的型別相容,那麼值就被儲存到屬性中,然後返回true。如果值型別不相容,屬性的值就不會發生改變,就會返回false。但是如果對應名字的屬性不存在,那麼乙個新的屬性就誕生了,以傳入的名字為名,以傳入的值為值,但是依然會返回false。這表示返回值不能用於確定乙個屬性是否被設定值,除非你已經知道這個屬性已經存在於qobject中了。

注意動態屬性被新增到單個實現的基礎中,也就是,被新增到qobject,而不是qmetaobject。乙個屬性可以從乙個例項中刪除,通過傳入屬性的名字和非法的qvariant值給qobject::setproperty()。預設的qvariant構造器構造乙個非法的qvariant。

動態屬性可用qobject::property()來查詢,就行使用q_property()宣告的屬性一樣。

通過自定義型別來構造q_property()的靜態型別,這樣可以被用以在動態型別中使用。

QT 屬性系統

最近學習了python 的描述器,想起之前學過的qt 的屬性系統,特此過來記錄一下。qt的屬性系統需要借助元物件來實現 q property type name read getfunction write setfunction reset resetfunction notify notifys...

QT屬性系統

qt提供乙個q property 的巨集來定義屬性 read write member 指定乙個成員變數與屬性的關聯,成為可讀可寫屬性,無需子啊設定read,write屬性 reset 可選,設定乙個屬性預設值 notify 可選,設定乙個訊號,屬性變換的時候發射訊號 designable 是否在 ...

6 Qt 之屬性系統

qt提供乙個類似於其它編譯器 商提供的複雜屬性系統 property system 然而,作為乙個編譯器和平台無關的庫,qt不能夠依賴於那些非標準的編譯器特性,比如 property或者 property qt的解決方案適用於qt支援平台下的任何標準c 編譯器。它依賴於元物件系統 meta obje...