## 13.3 元對象系統
Qt 的元對象系統是一個基于標準 C++的擴展,能夠使 C++更好的適應真正的組件 GUI 編程。它為 Qt 提供了支持對象間通信的信號與槽機制、實時類型信息和動態屬性系統等方面的功能。
元對象系統在 Qt 中主要有以下三部分構成:QObject 類、Q_OBJECT 宏和元對象編譯 器 moc。
1\.元對象系統機制
Qt 的主要成就之一是使用了一種機制對 C++進行了擴展,并且使用這種機制創建了獨 立的軟件組件。這些組件可以綁定在一起,但任何一個組件對于它所要連接的組件的情況事 先都不了解。
這種機制稱為元對象系統(meta-object system),它提供了關鍵的兩項技術:信號-槽以及內省(introspection)。內省功能對于實現信號和槽是必需的,并且允許應用程 序的開發人員在運行時獲得有關 QObject 子類的“元信息”(meta-information),包括 一個含有對象的類名以及它所支持的信號和槽的列表。這一機制也支持屬性(廣泛用于 Qt 設計師中)和文本翻譯(用于國際化),并且它也為 QtScirpt 模塊奠定了基礎。
標準 C++沒有對 Qt 的元對象系統所需要的動態元信息提供支持。 Qt 通過提供一個獨立 的 moc 工具解決了這個問題,moc 解析 Q_OBJECT 類的定義并且通過 C++函數提供可供使用 的信息。由于 moc 使用純 C++來實現它的所有功能,所以 Qt 的元對象系統可以在任意 C++ 編譯器上工作。
這一機制是這樣工作的:
(1) Q_OBJECT 宏聲明了在每一個 QObject 子類中必須實現的一些內省函數,如 metaObject()、QMetaObject::className()、tr()、qt_metacall(),以及其它一些函數。
(2) Qt 的 moc 工具生成了用于由 Q_OBJECT 聲明的所有函數和所有信號的實現。
(3) 像 connect()和 disconnect()這樣的 QObject 的成員函數使用這些內省函數來完成 它們的工作。
由于所有這些工作都是由 qmake 和 QObject 類自動處理的,所以很少需要再去考慮這 些事情,如果想進一步了解的話,也可以閱讀一下有關 QMetaObject 類的文檔和由 moc 生 成的 C++源代碼文件,可以從中看出這些實現工作是如何進行的。
2\.元對象工具(moc)
Qt 的信號和槽機制是采用標準 C++ 來實現的。該實現使用 C++ 預處理器和 Qt 所包括 的 moc(元對象編譯器)。元對象編譯器讀取應用程序的頭文件,并生成必要的代碼,以支 持信號和槽機制。
qmake 生成的 Makefiles 將自動調用 moc,所有需要使用 moc 的編譯規則都會給自動 的包含到 Makefile 文件中 。開發人員無需直接使用 moc 編輯、甚至無需查看生成的代碼。
除了處理信號和槽以外,moc 還支持 Qt 的翻譯機制、屬性系統及其擴展的運行時類型 信息。比如,Q_PROPERTY()宏定義類的屬性信息,而 Q_ENUMS()宏則定義在一個類中的枚舉 類型列表。 Q_FLAGS()宏定義在一個類中的 flag 枚舉類型列表,Q_CLASSINFO()宏則允許 你在一個類的 meta 信息中插入 name/value 對。它還使 C++ 程序進行運行時自檢成為可 能,并可在所有支持的平臺上工作。
元對象編譯器 moc(meta object compiler)對 C++文件中的類聲明進行分析并產生用 于初始化元對象的 C++代碼,元對象包含全部信號和槽的名字以及指向這些函數的指針。
moc 讀 C++源文件,如果發現有 Q_OBJECT 宏聲明的類,它就會生成另外一個 C++源文 件,這個新生成的文件中包含有該類的元對象代碼。例如,假設我們有一個頭文件 mysignal.h,在這個文件中包含有信號或槽的聲明,那么在編譯之前 moc 工具就會根據該 文件自動生成一個名為 mysignal.moc.h 的 C++源文件并將其提交給編譯器;類似地,對應 于 mysignal.cpp 文件 moc 工具將自動生成一個名為 mysignal.moc.cpp 文件提交給編譯 器。
3\.需要注意的問題
元對象代碼是 signal/slot 機制運行所必須的。用 moc 產生的 C++源文件必須與類實現 文件一起進行編譯和連接,或者用 #include 語句將其包含到類的源文件中。moc 并不擴展 #include 或者#define 宏定義,它只是簡單的跳過所遇到的任何預處理指令。
- 第 1 章 走近 Qt
- 1.1 Qt 簡介
- 1.2 Qt 紀事概覽
- 1.3 Qt 套件的組成(以 Qt4.5 為準)
- 1.4 Qt 的授權
- 1.5 Qt 的產品
- 1.6 Qt 的服務與支持
- 1.7 Qt 的最新進展
- 1.8為什么選擇 Qt
- 1.9 問題與解答
- 1.10 總結與提高
- 第 2 章 Qt 的安裝與配置
- 2.1 獲取 Qt
- 2.2 協議說明
- 2.3 安裝 Qt
- 2.4 配置 Qt4 環境
- 2.5 問題與解答
- 2.6 總結與提高
- 第 3 章 Qt 編程基礎
- 3.1 標準 C++精講
- 3.2 Windows 編程基礎
- 3.3 Linux 編程基礎
- 3.4 Mac 編程基礎
- 3.5 問題與解答
- 3.6 總結與提高
- 第 4 章 Qt 4 集成開發環境
- 4.1 常見的 Qt IDE
- 4.2 Qt Creator
- 4.3 Eclipse
- 4.5 問題與解答
- 4.6 總結與提高
- 第 5 章 使用 Qt 基本 GUI 工具
- 5.1 使用 Qt Designer 進行 GUI 設計
- 5.2 使用 Qt Assistant 獲取在線文檔與幫助
- 5.3 使用 Qt Demo 學習 Qt 應用程序開發
- 5.4 問題與解答
- 5.5 總結與提高
- 第 6 章 Qt 4 程序開發方法和流程
- 6.1 開發方法
- 6.2 Hello Qt
- 6.3 幾個重要的知識點
- 6.4 問題與解答
- 6.5 總結與提高
- 第 7 章 對話框
- 7.1 QDialog 類
- 7.2 子類化 QDialog
- 7.3 快速設計對話框
- 7.4 常見內建(built in)對話框的使用
- 7.5 模態對話框與非模態對話框
- 7.6 問題與解答
- 7.7 總結與提高
- 第 8 章 主窗口
- 8.1 主窗口框架
- 8.2 創建主窗口的方法和流程
- 8.3 代碼創建主窗口
- 8.4 使用 Qt Designer 創建主窗口
- 8.5 中心窗口部件專題
- 8.6 Qt4 資源系統專題
- 8.7 錨接窗口
- 8.8 多文檔
- 8.9 問題與解答
- 8.10 總結與提高
- 第 9 章 Qt 樣式表與應用程序觀感
- 9.1 應用程序的觀感
- 9.2 QStyle 類的使用
- 9.3 樣式表概述
- 9.4 使用樣式表
- 9.5 問題與解答
- 9.6 總結與提高
- 第 10 章 在程序中使用.ui 文件
- 10.1 uic 的使用
- 10.2 Ui_YourFormName.h 文件的組成
- 10.3 編譯時加入處理.ui 文件的方法
- 10.4 運行時加入處理.ui 文件的方法
- 10.5 信號與槽的自動連接
- 10.6 問題與解答
- 10.7 總結與提高 本章主要講解了以下內容:
- 第 11 章 布局管理
- 11.1 基本概念和方法
- 11.2在 Qt Designer 中使用布局
- 11.3 基本布局實踐
- 11.4 堆棧布局
- 11.5 分裂器布局
- 11.6 自定義布局管理器
- 11.7 布局管理經驗總結
- 11.8 問題與解答
- 11.9 總結與提高
- 第 12 章 使用 Qt Creator
- 12.1 Qt Creator 概覽
- 12.2 Qt Creator 的組成
- 12.3 快捷鍵和常用技巧
- 12.4 Qt Creator 構建系統的設置
- 12.5 處理項目間依賴關系( Dependencies )
- 12.6 Qt 多版本共存時的管理
- 12.7 使用定位器在代碼間快速導航
- 12.8 如何創建一個項目
- 12.9 實例講解
- 12.10 使用 Qt Creator 調試程序
- 12.11 問題與解答
- 12.12 總結與提高
- 第 13 章 Qt 核心機制與原理
- 13.1 Qt 對標準 C++的擴展
- 13.2 信號與槽
- 13.3 元對象系統
- 13.4 Qt 的架構
- 13.5 Qt 的事件模型
- 13.6 構建 Qt 應用程序
- 13.7 總結與提高
- 附錄 A qmake 使用指南
- A.1 qmake 簡介
- A.2 使用 qmake
- 附錄 B make 命令
- B.1 命令解釋
- B.2 使用 make 自動構建
- 附錄 C Qt 資源
- C.1Qt 官方資源
- C.2 Qt 開發社區