
Qt 背景与环境搭建从零理解跨平台 GUI 框架与开发环境一篇面向零基础读者、也方便我自己反复回看的中文复习笔记。把“Qt 是什么、它解决什么问题、为什么能跨平台、开发环境怎么搭、新建的项目里每一份文件各管什么、背后又发生了怎样的代码生成”一次讲透。写在前面我决定系统整理这一章是因为它同时回答了三个让我一开始模糊的问题第一GUI 程序到底是个什么东西为什么它和以前写的“黑框框”程序不是一回事第二市面上写桌面界面的方案那么多为什么偏偏要学 Qt第三装好 Qt 之后Qt Creator 帮我生成的那些main.cpp、widget.h、widget.cpp、widget.ui、.pro究竟各自扮演什么角色点一下运行按钮背后又跑了哪些工具。下面我用自己的理解重新讲一遍先建立宏观认知再落到环境搭建和项目结构。所有术语第一次出现时都会先给直观解释再给准确含义。知识框架先放一张总览图后面的章节基本就是按这张图的脉络展开从左到右是“客户端开发 → GUI 方案 → Qt 框架本身”从上到下是“为什么跨平台能打 → 怎么把环境搭起来 → 项目里有什么”。目录一、为什么 Qt 值得学客户端开发与 GUI 的世界1.1 客户端程序与服务器1.2 TUI 与 GUI两种交互界面1.3 客户端开发的范畴网页前端、桌面应用、移动应用1.4 Windows 下写图形界面的几种方案1.5 Qt 是什么跨平台 C GUI 应用程序框架1.6 框架与库的区别1.7 Qt 的发展、平台支持、版本与许可证二、开发环境三件套编译器、Qt SDK 与 Qt Creator2.1 为什么是“三件套”2.2 下载 Qt SDK2.3 安装时的注意点2.4 配置 PATH 环境变量三、用 Qt Creator 新建第一个项目3.1 Qt Creator 界面构成3.2 新建项目的关键选择3.3 一个高频坑中文路径导致构建失败四、Qt 项目里到底有什么文件结构与元编程4.1 自动生成的几份文件4.2 main.cpp程序入口4.3 widget.h 与 widget.cpp窗口类4.4 widget.ui用 XML 描述界面4.5 .pro 工程文件4.6 元编程构建流程qmake、uic、moc4.7 构建产物build 目录与 .exe五、基类继承关系与对象树5.1 QWidget、QMainWindow、QDialog5.2 对象树与半自动内存回收六、边界、限制与常见误区总结一、为什么 Qt 值得学客户端开发与 GUI 的世界1.1 客户端程序与服务器我先确认一个最基础的概念客户端client就是“直接和用户打交道的那一端程序”。我们平时打开的 Chrome 浏览器、音乐播放器、画图板本质上都是客户端——你点一下、它反馈一下交互发生在你和程序之间。和客户端相对的是服务器server它躲在客户端背后通过网络给客户端提供支撑。比如用打车软件你点“发送订单”时订单被发到服务器服务器再转发给附近司机的客户端。很多客户端程序背后确实依赖服务器但也有例外画图板、计算器这类程序断网也能用它依然直接和你交互所以同样算客户端。结论先记牢——客户端的范围很广不一定非得联网。1.2 TUI 与 GUI两种交互界面客户端开发最重要的任务之一是编写“和用户交互的界面”你在程序里看到的所有按钮、输入框、菜单都叫界面。界面按风格分成两类TUIText-based User Interface终端/命令行界面就是俗称的“黑框框”。它靠命令和键盘交互多见于给程序员用的专业软件。比如以前写 C/C 练手时跑起来的那些程序基本都是 TUI。GUIGraphical User Interface图形用户界面靠鼠标点击、窗口、按钮这些直观元素交互面向普通用户。图里左侧是 TUI输入命令、看文字输出右侧是 GUI窗口里摆着标题栏、按钮、输入框。两者目的都是“和用户交互”并没有高低贵贱之分。很多 TUI 软件如 GCC 编译器、GDB 调试器技术含量极高GUI 看起来高级也只是交互形式不同。只是 GUI 门槛低让不懂电脑的人也能用——这也是它普及的原因。 提示GUI 门槛低但“效率低”TUI 门槛高但“效率高”。举个例子给几百个文件批量重命名GUI 要一个个手动点TUI 几条命令就搞定。所以服务器领域几乎不用图形界面因为服务器是生产力工具靠命令行更顺手、也更省硬件资源。1.3 客户端开发的范畴网页前端、桌面应用、移动应用“开发”这个岗位还能细分其中和界面相关的一大支叫前端开发。广义的前端又叫大前端包含三类网页前端开发写网页浏览器里跑的程序桌面应用开发写电脑上的应用程序移动应用开发写手机上的应用程序。我们学的 Qt专门用来做桌面应用开发——给你电脑上写程序。它写不了网页前端做移动应用也几乎没人真拿它商用官方虽支持安卓/iOS但这两个领域各自有更成熟的技术体系。所以学习 Qt 的目标很明确桌面端 GUI 程序。图里把“大前端”拆成网页前端、桌面应用、移动应用三条路Qt 走的是中间那条——桌面应用而且是跨平台的。1.4 Windows 下写图形界面的几种方案既然 Qt 只是“写 Windows 图形界面”的方案之一我先横向看一遍历史方案才知道 Qt 特别在哪。下图的演进顺序是从早到晚Windows APIWindows 系统原生提供的接口。你可以调用它直接创建窗口、画矩形、处理鼠标事件。最原始也最繁琐但当年没得选只能硬着头皮用。MFCMicrosoft Foundation Classes上世纪 90 年代出现把 Windows API 按面向对象方式封装成类还提供可视化拖控件的设计器。曾和 VC6.0 双剑合璧独领风骚如今早已停止更新。Qt同样诞生于 1991 年前后也是面向对象封装系统 API 可视化界面设计器。和 MFC 不同Qt 至今仍在推陈出新生命力很强。C# / WinForms → WPF / UWP微软后来力推亲儿子 C# 语言配套 WinForms再升级出 WPF、UWP。但它们都不能跨平台。Electron最近几年火起来的开源方案本质是“把网页HTML打包成 Windows 客户端”。最大优点是能直接复用网页前端技术最大缺点是运行效率低于原生方案容易卡顿所以商业公司直接用它写客户端的并不多。横向比下来Qt 之所以“能打”是因为它一方面能跨平台Windows、Linux、macOS、嵌入式都支持另一方面运行效率不低。相比 MFC 太老、WPF/UWP 不能跨平台、Electron 效率偏低Qt 像是“六边形战士”。1.5 Qt 是什么跨平台 C GUI 应用程序框架回到定义Qt 是一个跨平台的 C 图形界面应用程序框架。拆开理解跨平台同一套代码能编译运行在多个系统上Windows / Linux / macOS / 嵌入式企业不用为不同系统各养一支开发团队成本大降。CQt 程序底层是 C 写的所以需要一个 C 编译器来编译。图形界面专门用来写带窗口、按钮这些视觉元素的程序。应用程序框架下面单独解释。跨平台这个词值得多想一层企业开发商业程序要算成本。如果为了支持更多系统每个系统单独招人重写成本极高而一套代码通吃多平台显然更香。这也是 Qt 在商业产品里被广泛采用的根本原因。1.6 框架与库的区别框架framework和库library容易被混为一谈但控制权相反库代码写好了让你调用你是主体决定用不用、在哪用。比如以前学的 STL 标准模板库就是库。框架框架先把大流程定好你配合框架去填细节框架是主体。你按它规定的骨架写代码大流程它帮你理顺小细节你自己补。一个类比下棋有“棋谱”定式照着棋谱下不会下得太差框架就像棋谱限制你的“自由”反而保证了代码下限。Qt 就是一套框架——它规定了“图形界面程序该怎么搭”你在关键环节塞自己的逻辑即可。C 生态相对割裂没有像 Java 的 Spring 那样“一统天下”的框架所以 Qt 这种被业界公认的框架在 C 里其实不多见在 GUI 领域基本就是事实标准。图用“控制权在谁手里”一句话点透库是你调用它控制反转在你框架是它反过来调用你控制反转在框架。Qt 属于后者。1.7 Qt 的发展、平台支持、版本与许可证发展脉络Qt 诞生于 1991 年同一年还有 Linux、Python、Git 等最早由奇趣科技Trolltech开发2008 年被诺基亚收购诺基亚曾主推 Qt 开发塞班系统应用2012 年诺基亚手机业务崩塌后转手给 Digia2014 年 Qt Company 从 Digia 独立分拆上市现由 Qt Company 维护。时间线从左到右标出四次易主Trolltech → 诺基亚 → Digia → Qt Company。兜兜转转二十多年Qt 至今仍是跨平台 GUI 框架的事实标准。支持平台Windows、Linux著名的 KDE 桌面环境就是基于 Qt 构建的、macOS以及嵌入式系统冰箱、洗衣机、路由器、工业设备里的控制界面这是 Qt 当前很重要的战场。版本最新是 Qt 6但本篇以Qt 5实际常用的 5.14.2为主。并不是越新越好——新版本可能带恶性 bug商业开发优先求稳普遍用一个成熟版本而非最新版。双许可证开源许可免费使用但按开源协议你基于 Qt 写的程序通常也要开源国内实际约束力较弱。商业许可向 Qt Company 付费购买买的本质是技术支持与服务——遇到搞不定的 bug对方派工程师帮你解决相当于“买个背锅侠”。图把两种授权并排开源许可免费但受协议约束商业许可付费买服务。学习阶段用开源许可足够公司要做闭源商用产品时再评估商业许可。 提示Qt 的优点可以归纳为三点——跨平台、接口简单容易上手、简化了内存回收半自动后面对象树一节会展开。这三点对 C 程序员很友好。二、开发环境三件套编译器、Qt SDK 与 Qt Creator2.1 为什么是“三件套”要写并运行一个 Qt 程序需要三类东西协同C 编译器把 C 源代码翻译成机器能执行的程序。常见编译器有 GCCLinux 下大名鼎鼎的编译器套件、cl.exeVisual Studio 自带的微软编译器。注意编译器 ≠ IDE编译器只是被 IDE 调用的一个小程序。Qt SDKSoftware Development Kit软件开发工具包开发 Qt 程序所需的“全家桶”里面包含各种工具、Qt 自带的类库、文档等。一般 Qt SDK 已经内置了一个 C 编译器——Windows 版内置的是MinGWMinimalist GNU for Windows可以理解成“Windows 上的 GCC/G”。所以装 Qt SDK 时勾上它就不必另装编译器。IDEIntegrated Development Environment集成开发环境写代码的地方提供语法高亮、代码补全、跳转、一键编译运行等。Qt 官方推荐Qt Creator开箱即用、无需额外配置最适合入门。⚠️ 易错点编译器如 MinGW 里的 g.exe和 IDEQt Creator是两回事。Qt Creator 只是“壳”真正把代码变成程序的是背后的编译器。类比很多语言都这套套路。比如学 Java 要装 JDK相当于 SDK IDE用第三方库/框架时装 SDK 往往是关键一步。以前学的标准 C 内容之所以没提 SDK是因为用的是标准库或系统库不需要额外安装。2.2 下载 Qt SDK下载原则是首选官方网站http://download.qt.io/archive/qt/。这里需要解释一个背景Qt 官网是境外站点访问或下载有时很慢甚至不通。作为开发者学会从官网自行获取安装包是一项基本技能实在搞不定时也可以走分享的网盘但长期还是要掌握官网下载这条路。本篇用的版本是5.14.2。选“比较新但不是最新”的版本原因前面说过太新可能不稳定。图里是官网的版本列表我们定位到 5.14.2 这一行下载那个约 2 GB 多的.exe安装包Qt SDK 本体。2.3 安装时的注意点安装基本是一路“下一步”但有几点必须留意账号与协议安装中可能需要注册 Qt 账号不想注册就先断开网络再装随后要同意开源许可证不同意无法继续。安装路径不要带中文、空格、特殊符号这是 Windows 下装软件的常识。虽然很多程序能兼容中文路径但总有程序兼容不好会引出后续一堆问题。老老实实用纯英文路径最稳。组件勾选最关键展开组件列表必须勾上MinGW 7.3 64-bit就是前面说的内置 C 编译器以及Qt Creator本身再勾一个同名的 MinGW 工具项。至于安卓支持、图表、WebEngine 这些额外功能选不选都行不关键。图里红框处就是要确保勾上的 MinGW 7.3 64-bit 与 Qt Creator。64 位毋庸置疑现在基本见不到 32 位系统了。如果你当初勾的是 MSVC 2017 那一项后面构建时就会走 Visual Studio 的编译器本篇不涉及。安装会占用两个多 GB 硬盘空间确保空间充裕。装完后先不启动 Qt Creator。2.4 配置 PATH 环境变量装好之后建议再配置一下PATH 环境变量。不配也能用但配了后续更方便否则某些操作会报错找不到动态库。先解释环境变量它是操作系统维护的一组“键值对”用来给进程传递信息。其中PATHWindows 上只有首字母大写Linux 上全大写PATH这个变量非常特殊——它记录了“去哪些目录找可执行文件”。你在“运行”框输入calc能打开计算器、输入mspaint能打开画图板就是系统去 PATH 里的目录逐个查找的结果。Windows 的环境变量窗口分上下两部分用户变量只对当前用户生效系统变量对所有用户生效。自己用的电脑配哪个都行。我们要做的是把 Qt SDK 里“包含一堆.exe和动态库如assistant.exe、各种Qt5*.dll”的那个bin目录复制下来新建一条加进 PATH。直觉理解环境变量有点像进程间留字条。我进程 A把“我在 301 房间”写进环境变量你进程 B读到就能找到我。我们配 PATH就是让 Qt Creator 以及将来运行的 Qt 程序能借助这个“字条”找到 SDK 里的工具和动态库否则一运行就弹窗说找不到 xxx.dll。三、用 Qt Creator 新建第一个项目3.1 Qt Creator 界面构成打开 Qt Creator界面看着复杂先认几个区域菜单栏最上方文件、编辑、构建、调试等菜单。左侧边栏模式欢迎、编辑、设计、调试、项目、帮助等标签页。写代码用“编辑”设计界面用“设计”帮助里集成了 Qt 官方文档。构建套件Kit选择器用来选“用哪套编译器/Qt 版本”来构建。我们装的时候只勾了 MinGW这里就只有 MinGW 一个选项。输出窗格下方编译输出、问题、应用程序输出等信息都在这。另外开始菜单里 Qt SDK 还附带几个独立工具assistantQt 官方离线文档查类/API 必备、designer独立的界面设计器其实已集成进 Creator、linguistQt 语言家做国际化/多语言切换、以及 MinGW 的命令行终端。 提示读文档是程序员必备技能。Qt 文档写作水平很高建议习惯直接看官方英文文档——你学了十几年英语搭配耐心读懂八九不离十没问题。3.2 新建项目的关键选择点击菜单栏“文件 → 新建文件或项目”按下面顺序走左侧选Application应用程序——我们要写的是带界面的应用程序。右侧选Qt Widgets Application——这是“图形界面程序”的项目模板。注意别选成 Qt Console Application那是无界面的控制台/TUI 程序。Qt 也支持 Python、Qt Quick 等方式本篇以传统 C Widget 为主。填写项目名和路径纯英文路径下一步。Build system构建系统选qmake。构建系统负责协调整个编译运行各环节。Qt 提供三种qmake老牌、传统本篇用、cmake非 Qt 专属、很多开源项目用、Qbs新一代但用的人少已逐渐不维护。我们固定用 qmake。基类Base class选QWidget——这是最简单的方式入门先挑最简单的切。选不同基类自动生成的类名随之变选 QMainWindow 类名就 MainWindow选 QWidget 就是 Widget。勾选Generate form生成界面文件这会生成一个widget.ui后面可用图形化方式拖控件设计界面。语言/翻译文件暂不选和国际化相关本篇不涉及Kit 选 MinGW版本控制按需最后完成。上图把七步串成一条线从打开 Creator 到最后自动生成那几份文件。记住两个关键开关——构建系统选 qmake、基类选 QWidget 并勾选生成 .ui路径全程英文。⚠️ 易错点第一次建项目时若把项目放在带中文的路径下比如桌面里的“代码”文件夹点击运行会构建失败。这是 Qt 新手极容易踩的坑。换成全英文目录如D:/code/empty后一路下一步再点左下角绿色三角运行按钮就能弹出一个空白窗口有标题栏、最小化/最大化/关闭按钮但里面什么都没有。后续要学的就是怎么改代码让窗口丰富起来。3.3 一个高频坑中文路径导致构建失败这里单独强调Qt 自身构建对中文路径兼容不好。创建项目的目录、乃至源码所在目录都尽量纯英文。构建失败时的典型现象是编译报错、输出窗格一堆红字把项目整体挪到英文目录重新打开即可。熟练之后新建一个 Qt 项目其实用不了 30 秒只是第一次每个环节都值得弄清楚。四、Qt 项目里到底有什么文件结构与元编程4.1 自动生成的几份文件新建好空白项目后Qt Creator 会生成这些文件和目录Headers/下放widget.h头文件Sources/下放main.cpp、widget.cpp源文件Forms/下放widget.ui界面文件工程根目录有empty.pro工程文件下面逐份看并把“点运行背后发生了什么”一并讲清。图把生成后的目录结构画成一棵树根是你建的项目文件夹下面挂 main.cpp、widget.h、widget.cpp、widget.ui、empty.pro外加并列的 build 目录编译产物。每个文件右侧标注了它管什么。4.2 main.cpp程序入口每个 C 程序都需要一个main函数作为入口。Qt 项目这份main.cpp一般不需要我们手动改用默认生成的即可#includewidget.h#includeQApplicationintmain(intargc,char*argv[]){QApplicationa(argc,argv);// 应用程序对象整个 GUI 程序必须有它Widget w;// 创建我们的窗口对象Widget 是自动生成的类w.show();// 让窗口显示出来没有这句就看不见窗口returna.exec();// 进入事件循环程序开始“跑”起来}逐个解释首次出现项int main(int argc, char *argv[])argc是命令行参数个数argv是具体参数内容数组。Qt 把它们交给QApplication方便程序接收启动参数。QApplication a(argc, argv)QApplication是 Qt 提供的“应用程序对象”类代表整个 GUI 程序的生命周期。写 Qt 图形界面程序必须有一个它的实例平时我们很少直接操作它用默认这段就行。Widget wWidget就是新建项目时自动生成的窗口类类名随基类选择变。这里创建它的一个对象。w.show()show()是 QWidget 提供的方法意思是“显示”。没有 show()窗口就不出现对应的hide()则是隐藏。这两个方法来自父类 QWidget因为我们自己的类继承了它自然就继承了这些方法——这正是面向对象的威力。a.exec()exec()让程序进入事件循环不断等待并处理鼠标点击、键盘输入等事件。这里要特别澄清Linux 里也有个exec函数进程程序替换像“夺舍”把当前进程代码换成另一个可执行文件Qt 里的 exec() 和 Linux 的 exec 毫无关系只是名字恰好相同。计算机里同一个术语在不同上下文含义不同很常见要结合语境判断。4.3 widget.h 与 widget.cpp窗口类widget.h是窗口类的声明#ifndefWIDGET_H#defineWIDGET_H#includeQWidgetQT_BEGIN_NAMESPACEnamespaceUi{classWidget;}QT_END_NAMESPACEclassWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parentnullptr);~Widget();private:Ui::Widget*ui;};#endif// WIDGET_H逐项解释#ifndef WIDGET_H / #define WIDGET_H / #endif这是头文件保护符header guard保证这个头文件在一个编译单元里只被包含一次避免重复定义。现在更推荐用#pragma once但 Qt 自动生成的写法也能用。#include QWidgetQt 的设定很贴心——你用哪个内置类就包含同名头文件。比如用QWidget就#include QWidget不用去查文档猜头文件名。有时类被其他头文件间接包含了就不必显式写等编译器报“找不到定义”再手动加即可。class Widget : public QWidget说明我们这个类继承自 QWidget。前面新建项目时选的基类最终就决定继承谁。QWidget、QMainWindow、QDialog 都是 Qt 内置类都以Q前缀开头。Q_OBJECT这是一个宏macro。C 语言/ C 里宏本质是“文本替换”Q_OBJECT展开后会生成一大堆代码用来支撑 Qt 的信号与槽机制后续专门章节讲。只要某个类想用信号与槽就必须写Q_OBJECT。Widget(QWidget *parent nullptr)构造函数带一个parent父对象指针参数。这关系到后面要讲的“对象树”——创建 Qt 对象时可以指定它的父节点挂载到对象树上由父节点统一回收内存。Ui::Widget *ui这个指针和widget.ui界面文件密切相关由 qmake 生成的代码来填充后面讲元编程时展开。widget.cpp是类的定义相对简单#includewidget.h#includeui_widget.hWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);// 把 .ui 描述的界面“装配”到当前窗口上}Widget::~Widget(){deleteui;// 析构时释放 ui 指向的对象}#include ui_widget.h这个头文件不是手写的是 qmake 根据widget.ui自动生成的下一节讲。ui(new Ui::Widget)与ui-setupUi(this)创建界面对象并调用setupUi()方法把.ui里描述的控件真正“搭”到当前窗口this上。setupUi是自动生成的代码名字不是特别直观但它就是干这件事。~Widget()里delete ui析构时释放界面对象配合对象树机制管理内存。4.4 widget.ui用 XML 描述界面widget.ui是界面文件。双击它Qt Creator 会调用集成的designer切换到图形化设计器中间是程序窗口画布左边是 Qt 内置控件按钮、输入框、单选/复选框等可拖拽右边是属性编辑区改控件的位置、文字、大小等行为。点回“编辑”标签能看到.ui文件的本体——它其实是一个XMLeXtensible Markup Language可扩展标记语言文件uiversion4.0classWidget/classwidgetclassQWidgetnameWidgetpropertynamegeometryrectx0/xy0/ywidth400/widthheight300/height/rect/propertypropertynamewindowTitlestringWidget/string/property/widget/ui解释首次出现项XML用成对的尖括号“标签”表示数据的格式和 HTML 是“表兄弟”语法结构相似。但区别关键HTML 的标签是固定的由标准组织定好浏览器都按同一规则解释XML 的标签由程序员自定义——Qt 的开发团队约定了ui、widget、property这些标签各自表示什么含义。这有点像我们以前学的“自定义应用层协议”标签含义是你赋予的。本篇不必深究每个标签只要知道.ui本质是一个 XML、用来描述“界面长什么样”即可。上面片段里x0/x y0/y width400/width height300/height描述窗口坐标和尺寸windowTitleWidget/windowTitle描述标题栏文字。4.5 .pro 工程文件empty.pro是 Qt 项目的工程文件也是 qmake 构建时的重要依据QT core gui greaterThan(QT_MAJOR_VERSION, 4): QT widgets CONFIG c11 SOURCES \ main.cpp \ widget.cpp HEADERS \ widget.h FORMS \ widget.ui解释QT core gui声明要引入哪些 Qt 模块核心模块、GUI 模块。CONFIG c11编译选项指定按 C11 标准编译。SOURCES / HEADERS / FORMS列出参与构建的源文件、头文件、界面文件。这部分不用我们手动维护——在 Creator 里新建文件时它会自动更新。可以把它类比成以前在 Linux 上写的MakefileMakefile 里规定“编译哪些文件、先编译谁后编译谁、怎么清理”.pro起到类似作用。区别在于语法完全不同而且 qmake 会根据.pro自动生成真正的 Makefile我们不用手写。Creator 已经把编译细节封装好点运行按钮就全自动。4.6 元编程构建流程qmake、uic、mocQt 有个核心特性叫元编程metaprogramming——简单说就是“用代码生成代码”。你写的代码并不是直接就拿去编译而是先调用 Qt 内置工具基于你的代码生成另一些 C 代码最后编译的是生成的代码。点击运行按钮背后流程如下qmake 读.pro→ 生成 Makefile把工程文件翻译成传统 Makefile我们不用手写。uicUser Interface Compiler界面编译器读widget.uiXML→ 生成ui_widget.h把 XML 描述的界面翻译成 C 代码里面有个Ui::Widget类和setupUi()方法正是widget.cpp里#include ui_widget.h和ui-setupUi(this)的来源。mocMeta-Object Compiler元对象编译器处理Q_OBJECT宏 → 生成moc_widget.cpp把Q_OBJECT展开成的信号与槽相关代码单独生成出来。最后由编译器MinGW 的 g把你写的代码 uic/moc 生成的代码一起编译链接产出可执行程序。如果想在命令行手动构建理解流程用关键两步是 qmake 生成 Makefile再用 MinGW 的 make 工具编译# 进入项目源码目录包含 .pro 文件的这一层cdD:/code/empty# 用 qmake 读取 .pro自动生成 Makefile无需手写 Makefileqmake empty.pro# 用 MinGW 配套的 make 工具按 Makefile 编译链接最终生成 .exemingw32-makecd是切换目录的命令change directoryqmake empty.pro让 qmake 以工程文件为依据产出 Makefilemingw32-make则是 MinGW 下的 make 程序按 Makefile 规则把源码编译成可执行文件。日常用 Creator 点运行按钮本质就是自动跑了这两条命令加更多细节。4.7 构建产物build 目录与 .exe运行一次之后在项目目录并列的位置会多出一个build-xxx开头的目录里面是构建过程产生的中间文件Makefile及Makefile.Debug/Makefile.Releaseqmake 生成的真正参与编译。再次印证“Qt 编译底层还是用 Makefile只是它自动生成不用我们手写”。ui_widget.huic 从widget.ui生成的头文件里面Ui::Widget类的setupUi()就负责按 XML 把界面搭出来。debug/、release/下的.o目标文件以及最终的.exe可执行程序。直接双击那个.exe效果和在 Creator 里运行完全相同——这就是我们最终交付的程序。五、基类继承关系与对象树5.1 QWidget、QMainWindow、QDialog前面新建项目时选了基类Qt 提供的三个常见基类关系是QWidget最基础的窗口/控件类所有界面元素的“老祖宗”。选它生成的是最简单的空白控件。QMainWindow一个“完整的应用程序主窗口”自带菜单栏、工具栏、状态栏等适合做正式软件主界面。QDialog对话框类比如“设置”“关于”这种弹窗。三者都继承自 QWidget所以 QWidget 提供的show()、hide()等方法它们都有。新建项目选哪个自动生成的类就继承哪个——本篇入门选最简单的 QWidget。5.2 对象树与半自动内存回收C 程序员最头疼的往往是内存泄漏。Qt 做了一套类似垃圾回收、但又不全自动的机制叫“半自动内存回收”靠对象树实现Qt 里大量对象创建时可以传一个parent父对象指针比如Widget(QWidget *parent nullptr)。这些对象会挂到一棵N 叉树不是二叉树一个节点可有多个子节点但只能有一个父节点上。当父对象被销毁时它会自动销毁所有子对象。于是我们不用手动delete每个子控件父节点“一锅端”既简化了释放、又把对运行效率的影响降到最低不像 Java/Python 那种全自动垃圾回收会拖慢性能。这就是widget.h里parent参数和widget.cpp里delete ui的用意所在Qt 用对象树帮我们管内存比纯手动new/delete省心又比全自动 GC 高效。图里父对象 QWidget 通过 parent 指针“罩着”一批子控件按钮、标签、输入框。父一销毁子全跟着释放你基本不用管 delete——这就是半自动内存回收的直观样子。六、边界、限制与常见误区exec() 不是 Linux 的 execQt 的a.exec()是进入事件循环和 Linux 进程替换的exec无关。类似地“栈/堆”这个词在数据结构、操作系统虚拟地址空间、GBM 里含义都不同面试时被问要先反问“您说的是哪个栈/堆”结合上下文答。中文路径是隐性雷项目目录带中文会导致构建失败全程用英文路径最稳。MinGW 与 MSVC 是两套编译器装 SDK 时勾 MinGW 就走 MinGW勾 MSVC 2017 就走 Visual Studio 的 cl.exe配置更麻烦、更容易错。本篇统一 MinGW。qmake 与 cmake 不是一回事qmake 是 Qt 传统构建工具cmake 是更通用的构建工具。本篇用 qmakeCreator 已封装细节。Qt 不是“什么都能写”它主攻桌面应用写网页前端和移动应用都不是它的主战场官方虽支持安卓/iOS但商用极少。最新版本未必最好商业开发优先稳定本篇用成熟的 Qt 5.14.2 而非最新 Qt 6。开源许可的约束要了解免费的开源许可通常要求你的程序也开源国内实际执行较松但作为开发者要知道这条规则存在付费商业许可买的是技术支持与服务。总结这一章把“为什么学 Qt”和“环境怎么搭”一次性打通了Qt 是一个跨平台的 C GUI 应用程序框架靠“框架约束 跨平台 接口简单 半自动内存回收”在众多 Windows 界面方案里脱颖而出搭环境本质是装一个 Qt SDK它已内置 MinGW 编译器并附带 Qt Creator再配好 PATH用 Qt Creator 新建项目时关键选择是 Qt Widgets Application、qmake、基类 QWidget、勾选生成.ui并务必避开中文路径一个 Qt 项目由main.cpp入口、widget.h/.cpp窗口类含Q_OBJECT宏和对象树parent、widget.uiXML 描述的界面、empty.pro工程文件组成背后由 qmake/uic/moc 做元编程生成代码最终编译出.exe。下一阶段就是从“空白窗口”出发往里拖控件、写信号与槽让界面真正能解决实际问题。标签Qt、C、GUI、跨平台、Qt Creator、环境搭建、元编程、信号与槽、对象树、CSDN 复习笔记GUI 应用程序框架靠“框架约束 跨平台 接口简单 半自动内存回收”在众多 Windows 界面方案里脱颖而出搭环境本质是装一个 Qt SDK它已内置 MinGW 编译器并附带 Qt Creator再配好 PATH用 Qt Creator 新建项目时关键选择是 Qt Widgets Application、qmake、基类 QWidget、勾选生成.ui并务必避开中文路径一个 Qt 项目由main.cpp入口、widget.h/.cpp窗口类含Q_OBJECT宏和对象树parent、widget.uiXML 描述的界面、empty.pro工程文件组成背后由 qmake/uic/moc 做元编程生成代码最终编译出.exe。下一阶段就是从“空白窗口”出发往里拖控件、写信号与槽让界面真正能解决实际问题。标签Qt、C、GUI、跨平台、Qt Creator、环境搭建、元编程、信号与槽、对象树、CSDN 复习笔记