Skip to content

年度总结 #34

@coldowl

Description

@coldowl

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
    一种可跨库边界工作的动态转换

也就是如下特性:

这些特性才是 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)。

元对象系统基本上依靠这三个方面:

  1. QObject 类为可利用”元对象系统“的对象提供了一个基类。
  2. 在类声明的私有部分中声明 Q_OBJECT 宏,就能启用元对象特性,例如动态属性、信号和槽。
  3. 元对象编译器(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 电脑一直跑到现在高性能的自动驾驶屏幕上。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions