资讯动态

Qt5.9 C++开发指南代码实战:环境配置与避坑指南

发布时间:2026/10/23 9:47:15 来源:尧图企业网站定制
简介这是一份面向Qt初学者的完整学习资料包包含《Qt5.9 C开发指南》PDF与配套分章代码。内容从安装Qt5.9 SDK、配置GCC/MSVC编译器与环境变量起步逐步讲解Qt Creator项目管理、代码编辑、调试与构建工具的使用并覆盖.pro工程文件、.qrc资源文件、事件驱动模型、QObject以及信号与槽机制等核心知识点适合希望系统掌握Qt5跨平台界面开发的C开发者。压缩包共2000个文件约315.24MB以PDF手册和216个cpp、255个h源码为主辅以89个ui界面文件、69个pro工程配置、45个qrc资源清单及大量bmp/jpg/ico图标图片还包含编译生成的dll/exe/lib库文件便于对照阅读与直接运行验证。教程从环境搭建逐步延伸到具体示例章节代码与文档一一对应可降低入门门槛并节省环境排错时间。目前已有990人浏览学习既适合自学也可作为课堂教学与快速查阅的配套资料。1. 为什么一本 2017 年的书今天还被当作 C/Qt 入行第一课先从结论说起Qt5.9 不是最新版甚至不是 LTS但《Qt5.9 C开发指南》的章节代码依然是很多嵌入式、桌面端团队给新人布置的第一份阅读材料。不是因为它新而是因为 Qt5 的 API 在 5.6 到 5.15 之间几乎没有破坏性变更你今天打开这本书照着敲一个信号槽编译出的程序在 Qt 5.12、5.14 上都能跑。这种稳定性在 GUI 框架里可以说是个异类也给了老书常读常新的资本。这本书配合的章节代码网上通常以某个压缩包的形式传播几个常见发行版大多解压后是一个多级目录。对新手来说真正的难点不是书的内容而是「怎么让书里的代码在当下环境里编译通过」。这本书默认的教学编译器是 Qt Creator 自带的 MinGW 套件而很多初学者电脑上早就装了别的环境一打开工程文件就报错。这种和环境搏斗的过程在我带过的几个模拟项目里都是出现频率最高的弃坑点——不是学不会是跑不起来。所以这篇就按一个一线工程师带着你把这个代码包从入门跑到进阶的完整路径来写拿到代码后先看什么、环境怎么对齐、基础工程怎么编译、数据库和网络这些关键章节怎么调参、以及最后几个我踩过无数次才知道的深坑。目标只有一个让你看完后能把这本书的代码在自己机器上跑起来而不是收藏进网盘吃灰。2. 拿到代码包先别急着编译目录结构与三份必读文件很多刚接触这本书的人第一反应是把压缩包整个解压然后找某个 .pro 文件双击。这个动作本身没错但顺序错了。我一般拿到任何 Qt 教程配套代码会先花 15 分钟摸清楚它的组织方式和目标 Qt 版本这能省掉后面大量莫名其妙的编译错误。2.1 识别代码包对应的 Qt 版本从 .pro 文件里读出真相这本书的配套代码不同发行版对应的 Qt 版本略有差异。书名写的是 Qt 5.9但个别章节示例可能用到了 5.9 之后才稳定的 API。打开任意一个章节目录下的 .pro 文件找到greaterThan(QT_MAJOR_VERSION, 4)这一行附近的注释和配置能看出作者的 Qt 版本线索。# 以某个章节工程为例查看其 pro 文件关键配置 cd Qt5.9CppDemo/Chap02/HelloWorld cat HelloWorld.pro.pro文件是 qmake 的工程描述文件。里面最值得看的是这三块QT core gui这行声明用到了哪些模块如果后面章节代码里加了QT network sql说明依赖更多模块编译时缺模块会在这里报错。greaterThan(QT_MAJOR_VERSION, 4): QT widgets这是为了兼容 Qt4 和 Qt5 的写法Qt5 默认不带 widgets 模块必须手动添加。TARGET和TEMPLATE定义了输出名称和工程类型TEMPLATE app表示生成可执行程序。参数说明如果你自己新建工程想模仿这本书的组织方式建议把TARGET改成有意义的项目名不要叫untitled。这点看起来很基础但实际在管理多个章节代码时默认命名会迅速变成灾难——你会在调试时分不清当前跑的是哪个程序。2.2 三个最容易忽略的全局文件.pro 工程文件、README 与 .user 文件代码包根目录下通常会有一个总体的 README 或者说明文档这个文件未必是作者写的也可能是某个重新打包者加的但内容往往非常关键——里面可能说明了这个包对应的 Qt 具体小版本号、需要安装的编译器套件甚至修复了某些章节代码的已知问题。# 代码包根目录常见文件清单 ├── README.md # 总体说明务必先读 ├── Chap02-HelloWorld # 章节目录命名方式各版本不同 ├── Chap03-QtWidgets ├── ... └── CMakeLists.txt # 部分新版配套包会附带 CMake 版本注意以下几点第一.user文件比如HelloWorld.pro.user是 Qt Creator 为当前用户生成的本地配置记录了打开工程时用的套件、构建目录等。如果你的电脑上装了多个 Qt 版本这个文件会指定一个不存在的套件路径导致打开工程时弹出「未配置编译器」之类的错误。我建议拿到代码包后先删掉所有.user文件让 Qt Creator 自己重新生成。这个动作虽然简单但能解决掉至少一半的打开工程报错问题。第二README 里如果写了「本代码基于 Qt 5.9.0 MinGW 32 位」那你最好直接装这个版本。OpenGL 相关章节如果用了较新的 API老版本 MinGW 会编不过。反过来说如果只是想跑基础控件和布局章节用 Qt 5.12 LTS 反而更省心这点我们下一章细说。第三部分重新打包版本会把所有章节的 .pro 文件改成msvc2015 64bit或msvc2017 64bit套件配置如果你用的是 MinGW就需要在 Qt Creator 里重新选择套件这个操作路径我们稍后给出。3. 搞不清的套件与编译器Qt5.9 代码在现装环境下的对齐方案新手最容易在这个环节翻车。你把代码解压后打开.pro文件时 Qt Creator 提示「No suitable kit found」或编译时报cannot find -lQt5Widgets这两个问题本质上是一回事你安装的 Qt 套件和目标代码期望的不匹配。3.1 Qt Creator 里怎么确认当前用的是哪个套件三步排查法我拿到一套 Qt 代码第一次编译前的固定动作是检查「项目 → 构建套件Kit选择」。Qt Creator 左侧菜单点「项目」图标中间会列出所有已配置的套件当前生效的那个会带一个勾选标记。操作路径 项目视图 - 构建套件选择器左下角显示当前套件名称 - 点击后展开所有可用套件 - 找到匹配的 qmake 路径和编译器名称排查要点按优先级排序qmake 的路径必须是某个 Qt 安装目录下的bin/qmake.exe如果你电脑上有多个 Qt 版本比如 5.9 和 5.15 共存这里最容易被搞混。编译器必须是 MinGW 32 位或 MSVC 64 位中的一种不能混搭。典型错误是 qmake 指向了 MinGW 的 Qt编译器却选了 MSVC这会导致链接阶段直接崩溃。调试器gdb的版本必须和编译器匹配否则断点打不上程序一跑就飞。3.2 这本书配套代码的套装选择建议MinGW vs MSVC 之争这本书的代码横跨了 Qt 基础的方方面面——从 QWidget 控件到 OpenGL 绘图再到网络、数据库。不同的章节对套件的敏感度完全不同。章节类型推荐套件理由基础控件 / 布局 / 信号槽MinGW 64 位 或 MSVC 2019代码没有特殊依赖随便哪套都能编OpenGL / 图形绘制MSVC 2019 64 位部分示例依赖较新的 OpenGL 函数MinGW 自带库偶尔缺符号数据库SQLite / MySQLMinGW 32 位书中默认使用自带 SQLite 驱动MinGW 下免配置网络通信两者均可注意防火墙和本地回环地址设置自定义插件 / 高级模块MSVC 2019插件编译涉及 ABI 兼容MSVC 下更稳定个人建议如果你只是跟着书走完前 15 章用 MinGW 64 位足够。如果要做 OpenGL 相关的第 18 章左右的内容建议单独建一个 MSVC 套件。不要在一台机器上同时装 32 位和 64 位两个版本后面数据库章节加载驱动时会把你折磨到怀疑人生。3.3 书里编译环境过旧换新版本后必改的 .pro 配置这本书编写时的 Qt 5.9 和现在的 Qt 5.15 或 6.x 之间有些默认行为变了。你拿着 5.9 的代码直接在 5.15 上编最常见的报错是error: QTextCodec file not found这不是代码写错了而是 Qt 5.10 之后把QTextCodec从QtCore移到了QtCore5Compat模块。如果 README 里没提这事你要自己改.pro文件# 在 .pro 文件中增加旧模块兼容以处理 QTextCodec 等被封存的类 QT core5compat3.4 一条命令验证环境是否可用最小工程编译测试在你开始逐个章节跑代码前先花五分钟建一个空工程验证环境。这一步能区分「环境彻底坏了」和「这本书的代码有兼容问题」——如果空工程能跑而书里的代码不能跑问题在代码本身如果空工程都跑不起来你的 Qt 安装大概率有硬伤。# 用 qmake 和 make 在命令行手动编译一个最小工程 mkdir /tmp/hello_qt cd /tmp/hello_qt cat main.cpp EOF #include QApplication #include QLabel int main(int argc, char *argv[]) { QApplication a(argc, argv); QLabel label(Hello Qt); label.show(); return a.exec(); } EOF cat hello.pro EOF QT widgets TARGET hello SOURCES main.cpp EOF # 构建Windows 上用 mingw32-make qmake make ./hello参数说明QT widgets是必须的如果漏掉这行QApplication和QLabel会报 undefined reference。命令行编译可以帮助你绕过 Qt Creator 的壳直接看到真实的编译错误信息。很多新手在图形界面里看到一堆红色输出就蒙了其实打开命令行窗口跑一次错误本质往往一目了然。4. 从第一章到最后一章核心章节的编译思路与依赖配置这本书的章节推进逻辑很典型从信号槽起步到控件样式、布局管理再到事件系统、绘图、数据库、网络最后是并发和自定义插件。代码包里的每个子工程在动手编译前都要先想清楚它依赖哪几个 Qt 模块。4.1 信号槽与基础控件的 .pro 依赖最小依赖原则前几章是非常常规的 Widgets 程序依赖只有core gui widgets。三行配置就能编基本不会出意外。唯一要留意的是如果你用 Qt 6.x 去打开 5.9 的工程QtWidgets模块已经独立出来.pro文件里必须显式包含widgets否则链接失败。# 最小信号槽工程完整 .pro 文件示例 QT core gui greaterThan(QT_MAJOR_VERSION, 4): QT widgets TARGET signal_slot_demo TEMPLATE app SOURCES main.cpp mywidget.cpp HEADERS mywidget.h4.2 数据库章节SQLite 免配置但要注意驱动版本数据库章节通常用的是QSqlDatabase配合 SQLite 驱动。在 Windows 上Qt 官方安装包自带的 SQLite 驱动是qsqlite.dll位于 Qt 安装目录的plugins/sqldrivers下。如果你的.pro文件里加了QT sql却仍报driver not loaded基本就是插件目录没被找到。# 数据库工程关键配置注意 include 路径和 sql 模块 QT core gui sql greaterThan(QT_MAJOR_VERSION, 4): QT widgets SOURCES main.cpp运行时的排查就一条检查QCoreApplication::libraryPaths()返回的路径里是否包含你的 Qt 插件目录。// main.cpp 中输出所有可用数据库驱动 #include QSqlDatabase #include QDebug int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); qDebug() Available drivers: QSqlDatabase::drivers(); // 期望输出有 QSQLITE如果输出为空逗号分隔列表 // 说明 sqldrivers 目录没被加载 return 0; }参数说明QSqlDatabase::drivers()输出的是编译进 Qt 的所有数据库驱动名。如果列表里根本没有 QSQLITE说明插件路径不对需要在 main 函数前调用QApplication::addLibraryPath(你的 Qt 安装路径/plugins)。对于 MySQL 驱动这本书老版本没有直接配当年是出了名的棘手不建议新手在这一节停留太久。4.3 网络章节官方示例的本地回环测试与防火墙端口网络历来是代码包问题最多的章节这个问题能在代码包里踩出不同的状况。QTcpServer测试时如果防火墙弹出提示请务必允许专用网络下的访问否则卡死你几个小时。// TCP 回环测试监听 127.0.0.1避免防火墙对公网端口的拦截 QTcpServer server; bool ok server.listen(QHostAddress::LocalHost, 8888); if (!ok) { qDebug() listen failed: server.errorString(); }4.4 绘图和 OpenGL 章节的 include 与链接选项调整绘图章节一般是 QPainter 基础依赖gui模块就够了没什么坑。但 OpenGL 章节就不同尤其是书里的入门 GL 示例如果用较新的 Qt 版本编译可能会遇到glBegin在QOpenGLFunctions下不可用的情况。# OpenGL 模块配置 QT core gui opengl greaterThan(QT_MAJOR_VERSION, 4): QT widgets # 如果是 Qt 5.15后续基本要求改用 QOpenGLWidget # 但书籍版本 5.9 用的是 QGLWidget新版本可能已标记 deprecated注意QGLWidget 从 Qt 5.4 开始被标记废弃Qt 5.9 里警告已经很难压住Qt 5.12 以后虽然还能用但在 Qt 6.x 里被彻底移除。如果你的版本是 Qt 6这章的代码是完全跑不起来的需要自己重写为 QOpenGLWidget工程量不小。这章的代码我当年就吃过苦头编译没报错但运行时黑屏后来发现是 initializeGL 里的旧 API 在 OpenGL 3.2 Core Profile 下不生效。4.5 多线程章节显式链接 QtConcurrent 与头的差异Qt 的并发模块QtConcurrent在 Qt5.9 时期某些类需要单独.pro包含QT concurrent如果漏掉这行调用QtConcurrent::run()时会报undefined reference to QtConcurrent::run(...)或头文件找不到。这也是代码包中非常常见的坑因为很多学习者在 Qt Creator 里直接拖拽了某个新类自动模板会帮你加依赖但这里不会。任何时候遇到 undefined reference先检查.pro里是不是漏了模块这比检查代码本身更重要。4.6 自定义控件与插件章节影子构建目录带来的动态库加载坑书中偏后的章节涉及自定义 QWidget 插件这需要把生成的动态库放入 Qt 的插件目录。Qt Creator 默认开启「影子构建Shadow Build」生成的.dll在 build 目录里不在源码目录。你在运行时如果提示缺少插件文件用find搜一下就知道了# 找到构建生成的插件 dll 位置 find . -name *.dll -path *plugins*然后把它复制到 Qt 安装目录对应plugins/designer子目录。这里有个细节如果 Qt 是 64 位插件也要 64 位混用 32/64 位会导致 Qt Designer 启动失败这种问题特别容易在「我明明已经复制过去了怎么还不行」的场景里出现。5. 避坑指南这本书代码最常见的五个翻车现场任何讲解教程代码的文章如果只讲怎么编译不聊坑价值减掉一半。下面这五条是我真的在带新人或自己复现过程中踩过、也帮别人排过的雷全部按「现象 → 原因 → 解决」整理。5.1 现象一双击 .pro 以后界面是白的工程加载不出来现象Qt Creator 打开某个章节的.pro文件后左侧项目树空白或提示无法解析文件。原因这本书的配套代码有一部分用到了相对路径引用的.pri文件而.pri文件的路径是相对源码目录的。如果你把代码包解压后改了第一层目录的名字部分相对路径就断了。另一个常见原因是.pro文件编码不是 UTF-8老版本打包时可能是 GBK 或 ANSI 编码文件里有中文字符串就会导致解析失败。解决不要改目录名用 Qt Creator 打开前先用文本编辑器把.pro文件另存为 UTF-8如果依旧失败看看.pro里是不是有include(../common/common.pri)这类写法确认上一级目录里的 common 文件夹是否安然无恙。5.2 现象二新增的类文件都能看到编译时报「No such file or directory」现象代码包解压后目录里明明有myclass.cpp编译却报找不到这个文件。原因.pro文件里的SOURCES 没有包含这个新文件或者用了通配符但路径不对。这本书的部分章节代码为了清晰会手动把每个文件列出来。你如果已经从别的工程里拷贝了新的.cpp和.h文件但忘了往.pro里加就会出现这个报错。解决右键工程名 → 「添加现有文件」或者直接编辑.pro把文件名加进SOURCES和HEADERS。这里有个通用经验大概率是SOURCES漏加而不是路径问题。你可以用qmake -project自动生成一个新的.pro文件但会覆盖原文件里的QT 配置不推荐除非你知道怎么改回来。5.3 现象三编译通过了但运行时窗口闪退或程序直接崩溃现象构建成功没有报错但点绿色运行按钮窗口刚弹出来就没了或者直接段错误。原因常见于以下三种一是使用了空指针比如ui-setupUi(this)之前就调用了某个控件指针二是信号槽语法在新版本里的类型检查不一致Qt 5.9 时期部分代码用旧式SIGNAL/SLOT宏运行时的 connect 失败不会编译报错三是插件或数据库驱动加载失败后代码只写了qDebug不退出但实际往下走会崩。解决把运行模式从 Release 切到 Debug或者命令行设置QTWEBENGINE_CHROMIUM_FLAGS--single-process等调试开关。另外强烈建议加一行qInstallMessageHandler(0); // 取消自定义日志恢复默认这样 Qt 的 warning 输出会带回at 文件行号可以定位崩溃位置。这个技巧我在多个新旧项目里救过场。5.4 现象四数据库驱动加载不了QSqlDatabase: QSQLITE driver not loaded现象编译没问题运行输出这个 error。原因Qt 程序在查找数据库驱动时使用编译时记录的插件路径。如果你把 Qt 安装目录移动过、或者用别的电脑上拷贝过来的可执行文件在另一台机器运行就会找不到sqldrivers。解决最简单的是把可执行程序放到 Qt 安装目录的bin下运行或者手动把plugins/sqldrivers目录复制到你的可执行文件旁的sqldrivers目录。对新手直接在工程配置里加一个 post-link 步骤自动拷贝驱动文件也是常见做法。# 工程文件末尾追加 CONFIG file_copies copydata.files $$[QT_INSTALL_PLUGINS]/sqldrivers/qsqlite.dll copydata.path $$OUT_PWD/sqldrivers copydata.CONFIG no_link INSTALLS copydata参数说明$$[QT_INSTALL_PLUGINS]是 Qt 官方安装包的宏路径能帮你在不同机器上自动找到插件目录。注意file_copies 方式在 Qt Creator 里属于旧做法新版 CMake 工程更多用add_custom_command但对这本书的 qmake 时代代码这种写法足够直接。5.5 现象五OpenGL 窗口黑屏或显示「QOpenGLShader: 着色器编译失败」现象程序窗口正常弹出但内容黑屏或者输出 Shader 编译错误日志。原因这本书编写时的 OpenGL 章节部分用了 GLSL 120 的语法版本而你的电脑显卡驱动默认提供了 OpenGL 3.3/4.x Core Profile对老版本 GLSL 的兼容性在不同平台差异极大。Windows 下 Intel 核显尤其明显。解决在 main 函数里强制设置 OpenGL 版本为 2.0 或 3.0QSurfaceFormat format; format.setRenderableType(QSurfaceFormat::OpenGL); format.setProfile(QSurfaceFormat::CompatibilityProfile); format.setVersion(2, 1); QSurfaceFormat::setDefaultFormat(format);6. 把书读厚从跑通代码到建立自己的 Qt 调试心法如果你跟着章节代码把前面几个模块都跑通了下一步不是急着往下继续看书而是回头做一件我认为最重要的整理工作把这套代码的构建过程固化成一个自己的模板工程。这本书的章节组织方式是一个章节一堆独立工程但真实项目里通常是一个大工程里多个.pro子工程用到了CONFIG ordered和SUBDIRS来组织。我给一个我在多个模拟项目中采用的模板结构# 根目录总 pro 文件示例 TEMPLATE subdirs CONFIG ordered SUBDIRS \ data_models \ ui_controls \ network_services \ db_plugins参数说明TEMPLATE subdirs表示这是一个工程集合ordered保证打包时按顺序优先构建因为某些子工程会在后置宏里引用前面生成的动态库。每个子目录里的.pro都要是完整的独立工程然后并行配置。一个更好的进阶动作是写一个自动化构建脚本用qmake和make把每个子工程都全局编译一遍把失败信息输出到一个文件里而不要用 Qt Creator 一个一个点。脚本跑完之后看汇总你会对「哪些章节依赖哪些模块」形成直觉这种直觉是新手的空白也是团队里老手值钱的地方。# 单目录递归编译全部 Pro 工程 for pro in $(find . -name *.pro); do dir$(dirname $pro) cd $dir qmake make -j4 2 ../build_errors.log cd - done说到调试习惯我最后想分享一个第一人称教训旧书配新环境的调试第一反应永远应该是「差异在哪」而不是「错在哪」。当年我第一次拿这本书的代码在 Qt 5.12 上编译遇到一个QLineEdit::textChanged信号重载导致 connect 歧义的报错我花了半小时读文档最后发现是旧式 SIGNAL 宏里参数写得太宽泛新 Qt 的 connect 捕获有更高精度需要显式指定参数类型。这个问题的本质不是代码错了而是 Qt 的演进让旧写法变得「不安全」了。另一个更基础的习惯是每跑通一个新章节就写一行注释记录你改了.pro的什么。这本书代码包原版在当当配套资料里有时候会被新版本迭代替换你改过的部分在下一次重新下载时会全部丢光。保持自己的一份注释记录比重新试错强十倍。希望这篇能帮你少走点当年我走过的弯路。把时间花在理解信号槽怎么串起你的业务逻辑上而不是浪费在「为什么这个库没链接上」这种毫无成就感的排查里。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑