## 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 开发社区