6 Qt 之屬性系統

2021-09-28 19:13:43 字數 3389 閱讀 7664

qt提供乙個類似於其它編譯器**商提供的複雜屬性系統(property system)。然而,作為乙個編譯器和平台無關的庫,qt不能夠依賴於那些非標準的編譯器特性,比如:__property或者[property]。qt的解決方案適用於qt支援平台下的任何標準c++編譯器。它依賴於元物件系統(meta object sytstem) - 通過訊號和槽提供物件間通訊機制。

要宣告乙個屬性,在繼承qobject的類中使用q_property()巨集。

q_property(type name

(read getfunction [write setfunction] |

member membername [(read getfunction | write setfunction)])

[reset resetfunction]

[notify notifysignal]

[revision int]

[designable bool]

[scriptable bool]

[stored bool]

[user bool]

[constant]

[final])

以下是摘自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訊號必須被指定,這樣才能被qml使用。

q_property(qcolor color member m_color notify colorchanged)

q_property(qreal spacing member m_spacing notify spacingchanged)

q_property(qstring text member m_text notify textchanged)

...signals:

void colorchanged();

void spacingchanged();

void textchanged(const qstring &newtext);

private:

qcolor m_color;

qreal m_spacing;

qstring m_text;

乙個屬性的行為就像乙個類的資料成員,但它有通過元物件系統訪問的附加功能。

注意:q_property字串不能包含逗號,因為逗號會分割巨集的引數。

通過名稱訪問屬性,能夠讓你在編譯時訪問不了解的類。你可以在執行時期通過qobject、qmetaobject和qmetaproperties查詢類屬性。

qobject *object = ...

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

int count = metaobject->propertycount();

for (int i=0; iproperty(i);

const char *name = metaproperty.name();

qvariant value = object->property(name);

...}

上面的**片段中,qmetaobject::property()用於獲取未知類中每個屬性的metadata。從metadata中獲取屬性名,然後傳給qobject::property()來獲取當前物件的屬性值。

假設我們有乙個類myclass,它從qobject派生並且在其private區域使用了q_object巨集。我們想在myclass類中宣告乙個屬性來追蹤乙個priority值。屬性的名稱是priority,它的型別是定義在myclass中的priority列舉。

我們在類的private區域使用q_property()來宣告屬性。read函式名為priority,並且我們包含乙個名為setpriority的write函式,列舉型別必須使用q_enum()註冊到元物件系統中。註冊乙個列舉型別使得列舉的名字可以在呼叫qobject::setproperty()時使用。我們還必須為read和write函式提供我們自己的宣告。

myclass的宣告看起來應該是這樣的:

class myclass : public qobject

; q_enum(priority)

void setpriority(priority priority)

priority priority() const

signals:

void prioritychanged(priority);

private:

priority m_priority;

};

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

給定乙個指向myclass例項的指標,或乙個指向qobject(myclass例項)的指標時,我們有兩種方法來設定priority屬性:

myclass *myinstance = new myclass;

qobject *object = myinstance;

myinstance->setpriority(myclass::veryhigh);

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

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

被屬性使用的自定義型別需要使用q_declare_metatype()巨集註冊,以便它們的值能被儲存在qvariant物件中。這使得它們適用於在類定義時使用q_property()巨集宣告的靜態屬性,以及執行時建立的動態屬性。

與屬性系統相對應的是乙個附加巨集 - q_classinfo()。用於新增name-value對到類的元物件中。例如:

q_classinfo("version", "3.0.0")
和其它meta-data一樣,類資訊可以在執行時通過meta-object訪問,詳情見:qmetaobject::classinfo() 。

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 是否在 ...

Qt屬性系統

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