系統介紹
qt 元物件系統(meta-object system)
qt的元物件系統基於如下三件事情:
1. 類:qobject,為所有需要利用元物件系統的物件提供了乙個基類。
2. 巨集:q_object,通常可以宣告在類的私有段中,讓該類可以使用元物件的特性,比如動態屬性,訊號和槽。
3. 編譯器:元物件編譯器(moc)為每個qobject子物件自動生成必要的**來實現元物件特性。
moc工具會讀入c++的原始檔,如果它發現了乙個或者多個宣告了q_object巨集的類,它就建立另乙個c++原始檔,為每個類生成包含元物件實現的**。這些編譯生成的原始檔通常都已經被包含到類的原始檔中或者和類的實現同時被編譯和鏈結。
除了為物件間的通訊提供訊號和槽(signals and slots)機制之外,元物件的**還提供下列特性:
· qobject::metaobject()返回與該類繫結的meta-object物件。
· qmetaobject::classname()可以在執行時以字串的形式返回類的名字,不需要c++編譯器原生的執行時型別資訊(rtti)的支援。
· qobject::tr()和qobject::trutf8()提供國際化支援,將字串翻譯成指定的語言。
· qobject::setproperty()和qobject::property()通過名字動態設定和獲取物件屬性。
· qmetaobject::newinstance()構造該類的乙個新例項。
除此之外你還可以用qobject_cast()動態轉換qobject類的型別。qobject_cast()函式和標準c++的dynamic_cast()功能類似,只是其不需要rtti的支援,而且可以跨越動態連線庫的邊界。它嘗試將它的引數cast成尖括號內的物件型別,如果物件是正確的型別(執行時決定)則返回非零,否則返回0,說明物件型別不相容。
例如,假設mywidget繼承自qwidget,同時也宣告了q_object巨集,
qobject *obj = new mywidget;qobject型別的變數obj實際上指向乙個mywidget物件,因此我們可以這樣進行型別轉換:
qwidget *widget = qobject_cast(obj);到mywidget的轉型可以成功是因為qobject_cast()並沒有對qt內建物件和定製的擴充套件物件分別對待。
qlabel *label = qobject_cast(obj); // label is 0另一方面到qlabel的轉型則會失敗,指標會被設定為0。這樣使得我們可以在執行時根據物件型別,對不同型別的物件進行不同的處理:
if (qlabel *label = qobject_cast(obj)) else if (qpushbutton *button = qobject_cast(obj)) 儘管我們可以在不用q_object巨集和原物件資訊的情況下仍舊使用qobject作為基類,但是像訊號和槽以及其他這裡描述的特性將無法使用。從元物件系統的觀點來看,乙個沒有元物件**的qobject子類和其最接近的有元物件**的祖先是等同的。這也就意味著,qmetaobject::classname()將不會返回你的類的真實的名字,而是該類某乙個祖先的名字。
因此,我們強烈建議所有qobject的子類都是用q_object巨集,不管你實際上是否使用訊號和槽,以及屬性
Qt元物件系統
qmetaobject是負責元物件資訊的類,每個繼承自qobject的類都會有乙個qmetaobject物件,qobject物件共用該qmetaobject物件,給類提供遠多於c 預設的typeinfo提供的資訊。主要內容如下 1 類資訊 類 qmetaclassinfo q classinfo q...
Qt元物件系統
產生背景 qt的元物件系統為物件間的通訊提供了訊號槽機制 執行時型別資訊 動態屬性系統。核心內容 qt的元物件系統實現基於三方面 1.qobject基類。為能夠利用元物件系統的物件提供了乙個基類。2.q object巨集。用於實現元物件特性,如動態屬性 訊號槽。3.meta object compi...
QT元物件系統
物件間的訊號和槽機制。執行時型別資訊和動態屬性系統。必須繼承自qobject 在類宣告區域新增q object巨集。用於啟動原物件特性。元物件編譯器 moc 為每個qobject的子類,提供實現元物件特性所必須的 反射機制指的是在執行時,能獲取任意乙個物件的所有型別 屬性和成員函式等資訊的一種機制。...