-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Qt 是对 C++ 的再封装,如果不想一直写 q++ ,就得理解 Qt 在 C++ 之上替我们干了什么。
在 Qt 框架中,最基础、核心的两个模块是 Qt Core 和 Qt GUI 。
Qt GUI 模块依赖于 Qt Core。没有 Qt Core,Qt GUI 无法运行。简单来说,它们是“地基”与“上层建筑”的关系:Qt Core 提供逻辑支持,而 Qt GUI 在此基础上提供视觉呈现。
Qt Core
Qt Core 是 Qt 框架的灵魂,在 C++ 之上增添了很多功能:
- a very powerful mechanism for seamless object communication called signals and slots
一种非常强大的无缝对象通信机制,称为信号和槽 - queryable and designable object properties
可查询和可设计的对象属性 - hierarchical and queryable object trees that organize
可组织对象所有权的分层且可查询的对象树 - object ownership in a natural way with guarded pointers (QPointer)
通过受保护指针以自然的方式实现对象所有权管理 - a dynamic cast that works across library boundaries
一种可跨库边界工作的动态转换
也就是如下特性:
- The Meta-Object System 元对象系统
- The Property System 属性系统
- Object Model 对象模型
- Object Trees & Ownership 对象树与所有权
- Signals & Slots 信号与槽
这些特性才是 Qt 框架最伟大的地方,这个我们留到后面再说。
Qt Gui
Qt Gui 的工作也很重要。一提到 Qt ,人们就觉得这是一个带界面的程序,这归功于 Qt Gui 太全面好用了。
Qt Core 带来的特性非常适合图形界面方面的工作。
在此之上,Qt 扩展了与窗口系统集成、事件处理、图像和字体相关的能力,处理来自操作系统的绘制请求、鼠标/键盘输入、基本绘图。
"Write once, run everywhere "(一次编写,随处运行),适配几乎所有主流图形环境,如 X11, Wayland, Windows 窗口管理器等等。
这意味同一套代码,在不修改(或仅修改少量)的情况下,能运行在不同的窗口系统上。跨平台的桌面端应用开发太需要这个了。
而当时的 Linux 社区正苦恼于没有一个强大且统一的图形库,Qt 就像是黑暗中的一束光,于是 KDE 诞生了,当然这是后话了。
Qt GUI 模块中最重要的类有两个:
QGuiApplication 包含主事件循环,来自窗口系统和其他来源的所有事件都在此处进行处理和分发。它还负责应用程序的初始化和终止工作。
QWindow 表示底层窗口系统中的一个窗口。它提供了许多虚函数来处理来自窗口系统的事件(QEvent),例如触摸输入、曝光、焦点、按键和几何形状变化。
好了,整个 Qt 的主干就差不多这样了。现在我们来多聊聊 Qt Core 的五大特性,鉴于它们是如此的重要,你也可以称之为 Qt 框架的五大特性。
The Meta-Object System 元对象系统
Qt 的元对象系统提供了用于对象间通信的信号和槽机制(signals and slots)、运行时类型信息(run-time type)以及动态属性系统(dynamic property)。
元对象系统基本上依靠这三个方面:
- QObject 类为可利用”元对象系统“的对象提供了一个基类。
- 在类声明的私有部分中声明 Q_OBJECT 宏,就能启用元对象特性,例如动态属性、信号和槽。
- 元对象编译器(moc)为每个 QObject 子类提供实现元对象功能所需的代码。
元对象系统的设计初衷并非为了图形界面,而是为了解决 C++ 在 90 年代初的一些“先天不足”。
1991 年, Qt 雏形诞生的年份,那时的 C++ 还处于“草莽时期”,虽然仍是当之无愧的霸主,但也面临一系列窘迫的境地。
第一点就是标准缺失,第一份 C++ 国际标准(C++98)还要等 7 年才出。而且特性匮乏,当时 C++ 缺乏内省(反射)机制,没有标准化的信号传输方式。由于当时编译器太弱,无法实现复杂的模板编程(即后来的 STL 那套)。
一方面,人们需要 C++ 榨干底层硬件的性能,节省硬件成本。而现实的需要,又让人感觉 C++ 不够完美,迫切的渴望改变。Qt 团队因而发明了 MOC(元对象编译器)。这一设计在当时极具前瞻性,它绕过了 C++ 静态语法的限制,在 1991 年就实现了类似后来 Java 才有的动态特性。
也这是在这一年, Qt 的创始人通过 QObject 引入元对象系统和信号槽,本质上是在 C++ 还没准备好的时候,强行通过一套工具链(MOC)为 C++ 注入了“现代组件化开发”的基因。这种超前的设计,使得 Qt 能够跨越 30 多年,从 4MB 内存的 386 电脑一直跑到现在高性能的自动驾驶屏幕上。