当我们准备好 Qt Creator 的源代码之后,首先进入到它的目录,来看一下它的源代码目录有什么奥秘。 这里一共有 9 个文件夹和 9 个文件。我们来一一看看它们都是干什么用的。
- .git: 版本控制 git 的隐藏目录,这与 Qt Creator 代码没有关系。
- bin: 生成 Linux 平台 shell 脚本。
- dist: 安装文件配置信息和版本更新记录。
- doc: 生成 doxygen 文档的配置文件。
- qbs: QBS 配置文件。QBS,即 Qt Build Suite,是一种跨平台的编译工具,目的是将高层的项目描述(使用类似 QML 的语言)转换成底层的编译描述(供 make 等工具使用的信息)。它可以简化多平台的编译过程。QBS 与 qmake 类似,区别在于前者适用于任意项目,而后者一般仅供 Qt 项目使用。我们在阅读代码时将关注 qmake,不会深入研究 QBS 的使用。
- scripts: Qt Creator 使用的 perl 以及 python 等脚本。
- share: 源代码中所需要的一些非代码共享文件,例如代码模板等。
- src: Qt Creator 源代码文件。
- tests: Qt Creator 测试代码。
- .gitignore: git 忽略文件配置。
- .gitmodules: git 子模块配置。
- HACKING: Qt Creator 编码规范。
- LICENSE.GPL3-EXCEPT: GPLv3 协议。
- qtcreator.pri: Qt Creator 项目需要使用的通用配置,该文件一般会被 include 到大部分 pro 文件。
- qtcreator.pro: Qt Creator 的 qmake 项目文件。
- qtcreator.qbs: Qt Creator 的 QBS 项目文件。
- qtcreatordata.pri: Qt Creator 数据相关的配置。
- README.md: 有关如何编译 Qt Creator 等相关事宜的一些说明。
main()
着手。但是阅读 Qt 项目的源代码,我们也可以从 pro 文件开始。pro 文件是 Qt 项目组织结构,规定了我们希望该项目如何编译、编译之后要做什么操作等。 下面我们从根目录的 qtcreator.pro 开始。使用 Qt Creator 或者任意文本编辑器打开 qtcreator.pro,开始真正的代码阅读。
include(qtcreator.pri)
第一行是
include qtcreator.pri
。前面我们提到过,qtcreator.pri 中定义了很多函数和适用于各个模块的通用操作。pri 文件可以理解为 pro 文件片段,可以使用
include
操作符将其引入一个 pro 文件。qmake 会自动处理引用操作,类似于将 pri 文件的全部内容复制到
include
语句处。这与 C++ 的
#include
指令类似。这里的处理是线性的,也就是 qmake 会从上向下进行解析。因此,如果你在 pri 中定义了一个函数,那么必须在
include
语句之后才能正常使用该函数。这是在使用时需要注意的。有关 qtcreator.pri 文件的内容,会在以后的文章中详细介绍。如果你使用 Qt Creator 打开,
include
语句会在左侧的项目树中显示一个节点。这种节点不需要物理上的文件夹隔离,只需要
include
不同的 pri 文件即可。这样,即便你的所有文件都在同一个目录下,你也可以使用 pri 文件创建出来多个虚拟目录节点。这样的项目结构看起来会清晰很多。
#version check qt
!minQtVersion(5, 6, 0) {
message("Cannot build Qt Creator with Qt version ${QT_VERSION}.")
error("Use at least Qt 5.6.0.")
}
接下来的几行用于判断 Qt 的版本。
minQtVersion()
是在 qtcreator.pri 中定义的函数。没错!pro 也可以定义自己的函数!这正是 pro 的强大之处。我们会在后面详细介绍如何定义函数。顾名思义,这个函数函数用于判断 Qt 的版本。前面的
!
即取非运算符,这与 C++ 一致。当 Qt 的版本低于 5.6.0 时,执行块中的操作。
message()
是 qmake 预定义的函数,类似于
qDebug()
,可以在控制台输出一段文本。这里我们输出的是“Cannot build Qt Creator with Qt version $${QT_VERSION}.”。字符串最后的
$${QT_VERSION}
是占位符,会使用
QT_VERSION
变量的内容进行替换。这一操作被称为变量展开(variable expansion)。有关
$$
以及相关运算符的使用相当重要。
$$
运算符通常用于展开变量的内容,展开的内容可以用于变量的赋值,也可以用于函数的传参。例如:
EVER