现代Qt教程——0.2——第一个 CMake Qt6 工程从零跑通

张开发
2026/4/15 15:47:10 15 分钟阅读

分享文章

现代Qt教程——0.2——第一个 CMake Qt6 工程从零跑通
现代Qt教程——0.2——第一个 CMake Qt6 工程从零跑通相关仓库仍然已经开源正在积极火热的建设之中欢迎各位大佬提Issue和PR链接地址https://github.com/Awesome-Embedded-Learning-Studio/Tutorial_AwesomeQt1. 前言为什么非得用 CMake说实话我第一次接触 CMake 的时候内心是拒绝的。qmake 用得好好的为什么要换结果配了一天 CMake最后生成的还是一堆乱七八糟的文件。但后来我发现Qt 6 时代CMake 已经是唯一的选择了。qmake 虽然还能用但已经被官方标记为 “legacy”。而且 CMake 的威力是真的强大——跨平台构建、依赖管理、IDE 集成这些都不是 qmake 能比的。所以这一篇我们不搞虚的直接从零创建一个 Qt 6 的 CMake 工程。我会把每个字段、每个命令都解释清楚让你不仅知其然更知其所以然。2. 最小可运行的 Qt 程序在写 CMake 之前先让我们看看一个最小的 Qt 程序长什么样// main.cpp#includeQApplication#includeQLabelintmain(intargc,char*argv[]){QApplicationapp(argc,argv);QLabellabel(Hello, Qt 6!);label.resize(400,300);label.show();returnapp.exec();}就这么简单。但这背后Qt 的构建系统需要做很多事情MOCMeta-Object Compiler处理 Q_OBJECT 宏RCCResource Compiler把资源文件编译成 C 代码UICUser Interface Compiler把 .ui 文件转成 C 代码CMake 会自动调用这些工具前提是你的 CMakeLists.txt 写对了。3. CMakeLists.txt 逐行解析下面是一个标准的 Qt 6 项目的 CMakeLists.txt我会逐行解释# 1. 指定 CMake 最低版本 cmake_minimum_required(VERSION 3.26) # 2. 项目名称和语言 project(HelloQt VERSION 1.0 LANGUAGES CXX) # 3. 设置 C 标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 4. 自动处理 Qt 的 MOC、RCC、UIC set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) # 5. 查找 Qt6 包 find_package(Qt6 REQUIRED COMPONENTS Widgets) # 6. 创建可执行文件 add_executable(HelloQt main.cpp ) # 7. 链接 Qt 库 target_link_libraries(HelloQt PRIVATE Qt6::Widgets )3.1 逐字段解释字段作用为什么这样写cmake_minimum_required(VERSION 3.26)CMake 最低版本要求Qt 6.9.1 需要 CMake ≥ 3.26project(HelloQt VERSION 1.0 LANGUAGES CXX)项目名称和语言VERSION 会自动生成版本宏CMAKE_CXX_STANDARD 17C 标准Qt 6 需要 C17 或更高CMAKE_AUTOMOC ON自动运行 MOCQt 的信号槽机制需要CMAKE_AUTORCC ON自动运行 RCC资源文件图片、图标需要CMAKE_AUTOUIC ON自动运行 UIC.ui 界面文件需要find_package(Qt6 REQUIRED COMPONENTS Widgets)查找 Qt6 的 Widgets 模块REQUIRED 表示必须找到找不到就报错add_executable(HelloQt main.cpp)创建可执行文件第一个参数是名字后面是源文件target_link_libraries(HelloQt PRIVATE Qt6::Widgets)链接 Qt 库PRIVATE 表示这个链接只对 HelloQt 生效⚠️坑 #1CMAKE_PREFIX_PATH 没设置❌ 错误做法find_package(Qt6) 找不到不知道问题在哪✅ 正确做法配置时加上-DCMAKE_PREFIX_PATH/path/to/Qt/6.9.1/gcc_64 后果CMake 报错 “Could not find Qt6” 一句话记住CMake 需要知道 Qt 安装在哪里CMAKE_PREFIX_PATH 就是地图3.2 COMPONENTS 参数详解find_package(Qt6 REQUIRED COMPONENTS Widgets)里的COMPONENTS是什么意思Qt 6 是模块化的不同的功能在不同的模块里模块功能何时需要Widgets传统桌面控件QPushButton、QLabel几乎总是需要QuickQML/Qt Quick 现代界面写 QML 时需要Network网络编程QTcpSocket、QHttp做网络请求时需要Sql数据库QSqlDatabase、QSqlQuery操作数据库时需要WidgetsGUI 界面传统桌面程序你只需要引入你用到的模块。不需要的模块不要加否则会增加编译时间和最终程序大小。4. 从零创建项目4.1 创建目录结构# 创建项目目录mkdirHelloQtcdHelloQt# 创建文件touchmain.cpp CMakeLists.txt# 目录结构应该是这样# HelloQt/# ├── CMakeLists.txt# └── main.cpp4.2 写入代码把上面的 main.cpp 和 CMakeLists.txt 内容分别填入对应的文件。4.3 配置项目# 创建构建目录推荐 out-of-source 构建mkdirbuildcdbuild# 配置项目记得替换成你的 Qt 路径cmake..-DCMAKE_PREFIX_PATHC:/Qt/6.9.1/mingw_64# Linux 下cmake..-DCMAKE_PREFIX_PATH/home/你的用户名/Qt/6.9.1/gcc_64如果配置成功你会看到-- Configuring done -- Generating done -- Build files have been written to: /path/to/HelloQt/build4.4 编译运行# 编译cmake--build.# 运行Windows./Debug/HelloQt.exe# 运行Linux/WSL2./HelloQt如果一切顺利你会看到一个显示 “Hello, Qt 6!” 的窗口。随堂测验口述回答用自己的话说说为什么推荐 out-of-source 构建在 build 目录里编译(请先自己想一下再往下滑看答案)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━答案参考源码目录保持干净CMake 生成的文件都在 build 里方便清理构建产物直接删 build 目录就行避免污染 Git 仓库.gitignore 只需要忽略 build/━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━5. 常见编译错误及解决5.1 “Could not find Qt6”原因CMake 找不到 Qt 安装位置解决设置 CMAKE_PREFIX_PATHcmake..-DCMAKE_PREFIX_PATH/path/to/Qt/6.9.1/gcc_645.2 “The C compiler does not support C17”原因编译器太老解决升级编译器或者确保CMAKE_CXX_STANDARD设为 175.3 “moc_xxx.cpp not found”原因AUTOMOC 没开解决确保 CMakeLists.txt 里有set(CMAKE_AUTOMOC ON)5.4 “undefined reference to vtable for XXX”原因类里有 Q_OBJECT 但没有 moc 生成的代码被链接解决确保 AUTOMOC 开启把包含 Q_OBJECT 的头文件加到 add_executable 里随堂测验调试挑战以下 CMakeLists.txt 有问题请问哪里错了会导致什么后果cmake_minimum_required(VERSION 3.16) project(MyApp VERSION 1.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 14) find_package(Qt6 REQUIRED Widgets) add_executable(MyApp main.cpp) target_link_libraries(MyApp Qt6::Widgets) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ **答案参考** - VERSION 3.16 太低Qt 6.9.1 需要 ≥ 3.26 - C14 不够Qt 6 需要 C17 - find_package 缺少 COMPONENTS - target_link_libraries 缺少 PRIVATE - 缺少 AUTOMOC/AUTORCC/AUTOUIC ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ## 6. 进阶添加资源文件 Qt 项目常常需要添加图片、图标等资源。这时候需要用 .qrc 资源文件。 ### 6.1 创建资源文件 创建一个 resources.qrc 文件 xml !DOCTYPE RCC RCC version1.0 qresource fileimages/icon.png/file /qresource /RCC6.2 更新 CMakeLists.txtadd_executable(HelloQt main.cpp resources.qrc )CMake 会自动调用 RCC 把资源编译进可执行文件。6.3 在代码中使用#includeQApplication#includeQLabel#includeQPixmapintmain(intargc,char*argv[]){QApplicationapp(argc,argv);QLabel label;label.setPixmap(QPixmap(:/images/icon.png));label.show();returnapp.exec();}⚠️坑 #2资源路径冒号❌ 错误做法QPixmap(images/icon.png)// 直接用文件路径✅ 正确做法QPixmap(:/images/icon.png)// 用资源路径前面加冒号 后果程序运行时找不到图片或者发布后图片丢失 一句话记住资源路径用冒号前缀:/这是 Qt 资源系统的标识7. 进阶使用 .ui 文件7.1 创建 .ui 文件在 Qt Creator 里设计界面会自动生成 .ui 文件。或者手动创建一个简单的?xml version1.0 encodingUTF-8?uiversion4.0classMainWindow/classwidgetclassQMainWindownameMainWindowpropertynamegeometryrectx0/xy0/ywidth400/widthheight300/height/rect/propertypropertynamewindowTitlestringHello Qt/string/propertywidgetclassQWidgetnamecentralwidgetwidgetclassQPushButtonnamepushButtonpropertynamegeometryrectx150/xy120/ywidth93/widthheight29/height/rect/propertypropertynametextstringClick Me/string/property/widget/widget/widgetresources/connections//ui7.2 更新 CMakeLists.txtadd_executable(HelloQt main.cpp mainwindow.ui )7.3 在代码中使用#includeQApplication#includeui_mainwindow.hintmain(intargc,char*argv[]){QApplicationapp(argc,argv);Ui::MainWindow ui;QMainWindow window;ui.setupUi(window);window.show();returnapp.exec();}随堂测验代码填空补全以下 CMakeLists.txt使其能正确编译一个包含 .ui 文件的 Qt 项目cmake_minimum_required(VERSION ______) project(MyApp VERSION 1.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD __) set(CMAKE_AUTOMOC __) set(CMAKE_AUTOUIC ON) find_package(Qt6 ______ COMPONENTS Widgets) add_executable(MyApp main.cpp mainwindow.____ ) target_link_libraries(MyApp ______ Qt6::Widgets) *(提示3.26、17、ON、REQUIRED、.ui、PRIVATE)* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ **答案参考** cmake cmake_minimum_required(VERSION 3.26) project(MyApp VERSION 1.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) find_package(Qt6 REQUIRED COMPONENTS Widgets) add_executable(MyApp main.cpp mainwindow.ui ) target_link_libraries(MyApp PRIVATE Qt6::Widgets) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━8. 多模块项目结构实际项目中代码通常会分成多个模块MyApp/ ├── CMakeLists.txt ├── app/ │ ├── CMakeLists.txt │ └── main.cpp ├── core/ │ ├── CMakeLists.txt │ ├── core.h │ └── core.cpp └── resources/ └── app.qrc根目录的 CMakeLists.txtcmake_minimum_required(VERSION 3.26) project(MyApp VERSION 1.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) find_package(Qt6 REQUIRED COMPONENTS Widgets) add_subdirectory(core) add_subdirectory(app)core/CMakeLists.txtadd_library(core core.h core.cpp ) target_link_libraries(core PUBLIC Qt6::Widgets )app/CMakeLists.txtadd_executable(MyApp main.cpp ../resources/app.qrc ) target_link_libraries(MyApp PRIVATE core )9. 练习项目练习项目Qt 计算器功能描述创建一个简单的计算器程序支持加减乘除四种运算。✅完成标准使用 CMake 构建系统界面用 .ui 文件设计有数字按钮和运算符按钮有一个显示结果的 QLineEdit点击等号按钮能计算结果能处理除零错误提示CMakeLists.txt 需要链接 QtWidgets 模块.ui 文件需要加到 add_executable 里用 QLineEdit::text() 获取输入用 QDoubleLineEdit 转数字除零时显示 “Error”10. 官方文档参考 CMake 手册 - Qt 6 · Qt 官方的 CMake 使用指南 qt-cmake-standalone 测试 · CMake 命令参考 CMake 教程 · CMake 官方教程链接已验证2026-03-17 可访问到这里你的第一个 Qt 6 项目就跑通了掌握了 CMake 基本用法后面的项目构建都不在话下。下一节我们会深入 Qt 的核心——信号槽机制。━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━相关阅读入门 · 环境搭建 · 00 · Qt6 安装踩坑指南 - 相似度 80%现代Qt开发——0.1——如何在IDE中配置Qt环境 - 相似度 80%嵌入式C教程实战之Linux下的单片机编程7GPIO到底是什么 —— 通用输入输出的前世今生 - 相似度 80%

更多文章