qt提供了乙個複雜的屬性系統,類似於某些編譯器**商提供的屬性系統。 但是,作為與編譯器和平台無關的庫,qt並不依賴非標準的編譯器功能,例如__property或[property]。 qt解決方案可在qt支援的每個平台上與任何標準c ++編譯器一起使用。 它基於元物件系統,該元物件系統還通過訊號和插槽提供物件間通訊。
宣告屬性的要求
若要宣告屬性,請在繼承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;
屬性的行為類似於類資料成員,但它具有可通過元物件系統訪問的其他功能。
可以繼承read,write和reset函式。它們也可以是虛擬的。在使用多重繼承的類中繼承它們時,它們必須來自第乙個繼承的類。
屬性型別可以是qvariant支援的任何型別,也可以是使用者定義的型別。在此示例中,類qdate被認為是使用者定義的型別。
q_property(qdate date read getdate write setdate)
由於qdate是使用者定義的,因此必須在屬性宣告中包含標頭檔案。
由於歷史原因,作為屬性型別的qmap和qlist是qvariantmap和qvariantlist的同義詞。
使用元物件系統讀取和寫入屬性
可以使用通用函式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和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()用於獲取有關某個未知類中定義的每個屬性的元資料。從元資料中獲取屬性名稱,並將其傳遞給qobject :: property()以獲取當前物件中屬性的值。
簡單的例子
假設我們有乙個myclass類,它是從qobject派生的,並且在其私有部分中使用了q_object巨集。 我們想要在myclass中宣告乙個屬性以跟蹤優先順序值。 該屬性的名稱將是priority,其型別將是乙個名為priority的列舉型別,該列舉型別在myclass中定義。
我們在類的私有部分中使用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例項的指標或指向作為myclass例項的qobject的指標,我們有兩種方法來設定其優先順序屬性:
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_flag()。像q_enum()一樣,它註冊乙個列舉型別,但是它將該型別標記為一組標誌,即可以進行「或」運算的值。乙個i / o類可能具有列舉值read和write,然後qobject :: setproperty()可以接受read | write。寫。 q_flag()應該用於註冊此列舉型別。
動態特性
qobject :: setproperty()也可以在執行時用於向類的例項新增新屬性。當使用名稱和值呼叫它時,如果qobject中存在具有給定名稱的屬性,並且給定值與該屬性的型別相容,則該值將儲存在該屬性中,並返回true。如果該值與屬性的型別不相容,則不更改屬性,並返回false。但是,如果qobject中不存在具有給定名稱的屬性(即,如果未使用q_property()宣告),則會將具有給定名稱和值的新屬性自動新增到qobject中,但仍然為返回false。這意味著不能使用返回false來確定是否實際設定了特定屬性,除非事先知道該屬性已存在於qobject中。
請注意,動態屬性是按例項新增的,即它們是新增到qobject而不是qmetaobject的。通過將屬性名稱和無效的qvariant值傳遞給qobject :: setproperty(),可以從例項中刪除屬性。 qvariant的預設建構函式構造乙個無效的qvariant。
可以使用qobject :: property()查詢動態屬性,就像在編譯時使用q_property()宣告的屬性一樣。
屬性和自定義型別
需要使用q_declare_metatype()巨集來註冊屬性使用的自定義型別,以便可以將其值儲存在qvariant物件中。這使得它們既適用於在類定義中使用q_property()巨集宣告的靜態屬性,又適用於在執行時建立的動態屬性。
向類中新增其他資訊
連線到屬性系統的是附加巨集q_classinfo(),可用於將附加名稱-值對附加到類的元物件上,例如:
q_classinfo(「版本」,「 3.0.0」)
像其他元資料一樣,類資訊可以在執行時通過元物件進行訪問。有關詳細資訊,請參見qmetaobject :: classinfo()。
公司加薪制度
1.加薪制度 內向的中國人,對主動要求加薪這件事比較羞澀。根據調查,有51.3 的人說自己從來沒有向上司提出過 加薪 超過一半今日焦點 在年底考核中,如果有員工讓你特別滿意而考慮用加薪來獎勵他的時候,你一定要注意其他員工的感受。這可不是件小事。有接近一半的受訪者,比例為47.9 在加薪受到不公平待遇...
公司制度掠影
到了公司一年多了,終於因為被選作提建議的員工,有機會第一次看到傳說中的制度。不看不知道,發現不知道的東西真不少。摘抄一二 通訊費支出 手機費報銷除需提供相關發票外,還需提供由電信部門出具的費用彙總清單。裝置的維護 損壞與賠償 1 領用電腦的員工在日常使用時要負責好裝置的維護工作,每月需填寫 裝置使用...
oracle的 行省制度
oracle的內部空間結構非常複雜,就像乙個擁有龐大面積的國家一樣。因此,它也採取了自元朝以來沿襲下來的 行省制度 資料庫database,表空間tablespace,段segment,區extent,塊block,資料庫由乙個或多個表空間組成,表空間包含段,段包含區,區包含塊。這些所謂的表空間,段...