
VS2017 配 Qt5.14 这件事听起来像是装个插件、指一下 qmake 路径就能收工的活真动手做的时候八成时间都花在跟版本号较劲上装完插件菜单没出来、工程建好了死活找不到头文件、链接阶段一片 LNK2019、编译过了双击 exe 又弹缺少 Qt5Cored.dll。这些问题单独拎出来都不难但它们会在同一次配置里排队出现新手很容易在第三个坑的位置就放弃转头去装 Qt Creator 了。这篇内容围绕VS2017 Qt5.14这套组合把我从零开始配通的完整过程拆开讲为什么这两个版本的搭配是原配、VS2017 侧要提前确认哪些组件、Qt 安装包里哪些勾选项是负担、Qt VS Tools 的版本对应关系、Qt Versions 每一栏该填什么、模板工程生成出来后要检查什么以及各类报错背后的真实根因。适合手上已经有 VS2017、要在 Windows 上做 C 桌面开发的读者也适合从 Qt Creator 迁移过来、想用 VS 的调试器和debugger生态但不想重装工具链的人。下面按配置的先后顺序展开中间穿插几张报错对照表方便你直接按现象查原因。1. 先搞清楚哪套 Qt5.14 预编译包是为 VS2017 准备的1.1 Qt 官方 Windows 包里那几个 msvc 目录分别对应谁去 Qt 的下载页找 Qt5.14.2 的 Windows 包你会看到同一个版本下面挂着好几个 msvc 前缀的组件比如MSVC 2017 32-bit、MSVC 2017 64-bit有些小版本还会顺手带上MSVC 2015 32-bit/64-bit。这些不是随便选一个都行的同义词它们是用不同版本的编译器编译出来的预编译二进制里面的导入库、DLL、调试版 DLL 都是成对的。你把 VS2017 的工程指到 msvc2015 那一套上多数时候也能链上后面讲 ABI 的时候会解释原因但你就主动放弃了官方说明里明确支持的组合这个安全垫。这里有个很实际的推论Qt5.14 时代官方给 Windows 桌面端准备的预编译包就是把 VS2017以及更早的 VS2015当成主力编译器的。也就是说你在 VS2017 上配 Qt5.14用的是别人已经替你编译好、并且官方在持续验证的那一份二进制不需要自己从源码 build也不用担心某个模块漏编。这一点对刚开始做项目的团队特别重要——自己编译 Qt 是另一个量级的工作光是 configure 那一长串参数就够研究一整天而且 WebEngine 这类模块的编译时间可以按小时计。另外要留意的是 32 位和 64 位的区别。Qt5.14 的 32 位和 64 位包是两个完全独立的目录导入库不通用DLL 也不通用。你如果在 Qt 安装时只勾了MSVC 2017 64-bit但模板工程默认生成的是 Win32 平台配置那第一次编译必然失败。我的建议是如果你的项目没有必须用 32 位的理由比如要调用某个只有 x86 版本的旧 SDK、或者要跟 32 位的第三方 DLL 对接直接上 64 位勾选和工程配置都能少一半事。1.2 MSVC 2015/2017/2019/2022 的 ABI 兼容边界很多人被VS 版本必须严格一一对应的说法吓到其实 MSVC 的 C 运行时从 VS2015 到 VS2022 是刻意保持了二进制兼容的v140、v141、v142、v143 的 CRT 是向下兼容的关系。这意味着用 msvc2017 编译出来的 Qt 库理论上可以直接被 VS2019 或 VS2022 编译的工程链上去Qt VS Tools 里也能正常配置。搜索热词里那种高版本 VS 编译低版本工具集产物的场景——比如在 VS2022 里编译用 VS2017 工具集生成的目标模块——本质上依赖的就是这条兼容规则。但能链上和该这么干是两件事。我在实际项目里踩过的坑是主工程用 v142 编译链接了一个 v141 编译的第三方静态库而这个静态库内部又依赖特定版本的 CRT 行为比如某些 locale 相关的函数、或者 STL 容器的内存分配器跨模块传递运行期就会出现一些极难定位的崩溃或者内存告警。所以我的实践原则是Qt 用哪个 msvc 包工程就尽量用同代工具集。VS2017 就用 v141别为了顺手去切 v142。如果确实要用高版本 VS 打开老工程先在项目属性里把平台工具集固定成 v141确认能正常编译再考虑升级。混合工具集的项目把所有模块的/MD、/MDd运行时库设置统一不要出现一部分静态 CRT、一部分动态 CRT 的情况。顺带说一句VS2017 里能不能装 v141 工具集取决于你当时的安装选项。如果你安装 VS2017 的时候只勾了默认组件后面再用 VS2022 的安装器去管理可能发现 v141 不在列表里需要单独补装MSVC v141 - VS2017 C x64/x86 生成工具。这个组件装不上Qt 配好了也编不过。1.3 什么情况下该掉头去选 Qt5.12.10热词里出现VS2017 Qt5.12.10这种组合不是偶然。Qt5.12 是 LTS长期支持版本5.12.10 是这个系列的收尾版本修掉了大量早期问题而 Qt5.14 是常规发布版本生命周期短官方不会为它长期回补安全与兼容性修复。所以选型时我的判断标准是这样的场景建议版本理由企业内部长期维护的工具、要发布给客户Qt5.12.10 或更高的 LTS 线补丁可预期第三方库兼容验证充分学习、做 Demo、跟进较新特性Qt5.14.2语法和 API 较新预编译包齐全需要 Qt Quick 的新特性或较新的 WebEngineQt5.14.25.12 线在部分模块上偏旧项目已经跑在 5.12 上且稳定不升升级收益小于回归风险如果你的目标只是把 VS2017 Qt 跑通那么 5.12.10 和 5.14.2 在配置流程上是完全一致的Qt VS Tools 里换个 qmake 路径就行。真正会让人卡住的是混装同一台机器上装了 5.12 和 5.14 两套Qt Versions 里配了名字很接近的两条记录工程里选错了一条症状就是头文件能找到、链接却报符号缺失或者反过来。这个坑后面第六章会详细说。2. VS2017 这一侧要提前确认的三件事2.1 离线安装包里到底该勾哪些组件VS2017 最省事的装法是用官方安装器在线装但很多人尤其是内网环境需要离线包。离线包的做法是在能联网的机器上用安装器加--layout参数把安装文件下载到本地目录再把整个目录拷到目标机器运行目录里的安装程序。这里我不展开命令行细节重点是离线包的组件选择要在下载阶段就定下来因为离线布局只包含你当时勾选的东西事后再想加组件就得重新下载。针对 Qt 开发VS2017 侧至少要有这些工作负载里的使用 C 的桌面开发。单个组件里的MSVC v141 - VS2017 C x64/x86 生成工具这是 v141 工具集本体。一个 Windows 10 SDK版本可以选当前主流的注意 SDK 版本决定了你能用的 Windows API 和部分头文件。Windows 10 SDK对应的调试工具调试时查看调用堆栈、加载符号会用到。如果要做界面以外的活儿比如调 PaddleOCR 之类的推理库还需要对应的 C 运行库和 CMake 支持Paddle 的 C 推理库在 Windows 上通常以预编译包形式提供需要匹配你的工具集与位数配置流程跟 Qt 类似都是包含目录 库目录 附加依赖项三件套。有个容易被忽略的细节VS2017 社区版对个人开发者和小团队是免费使用的商业环境下的授权问题建议按贵司的合规流程走不要图省事绕开。我在团队里推工具链的时候第一件事就是把版本和授权这两件事在群里说清楚后面省掉很多麻烦。2.2 确认 v141 工具集和 Windows SDK 真的装上了装完之后别急着装 Qt先做一次自检打开 VS2017新建一个空的 C 控制台工程项目属性里看平台工具集下拉框里有没有Visual Studio 2017 (v141)。如果只有 v140 或者根本没有选项说明工具集没装全。接着编译一个 hello world确认能过这一步是排除VS 本身就有问题这个变量。再确认 SDK项目属性里Windows SDK 版本应该有一个默认值如果你安装了多个版本这里可以切换。有些第三方库比如某些版本的 OpenCV、Paddle 的预编译包对 SDK 版本有隐含要求版本太新或太旧都可能报找不到某个头文件。我的习惯是在团队统一一个 SDK 版本号写进项目文档避免每个人机器上默认 SDK 不同导致我这里能编你那里编不过。2.3 顺便说下插件生态Visual Assist 和 Qt VS Tools 的共存VS2017 时代很多人会装 Visual AssistVAX来做代码补全和重构热词里也能看到VS2017 assist 插件的搜索。VAX 和 Qt VS Tools 在绝大多数情况下能和平共处但有两个已知的相互影响值得提一句一是VAX 的解析器需要知道 Qt 的头文件路径否则它会把Q_OBJECT、signals、slots这些宏标成错误。VS2017 环境下 Qt VS Tools 会把包含目录注入到工程属性里VAX 通常能读到如果发现 VAX 报一堆红色波浪线但编译正常去 VAX 设置里手动补一下 Qt 的 include 目录或者让它重新解析工程。二是插件加载顺序和启动性能。同时装了好几个大插件VS2017 启动会明显变慢调试大工程时偶尔出现扩展导致 UI 卡住的情况。如果遇到莫名其妙的界面问题先用devenv /safemode启动一次确认是不是插件引起的再逐个禁用排查。3. Qt5.14.2 安装时的组件勾选与目录规划3.1 组件勾选清单哪些必装哪些是负担Qt 的 Windows 离线安装器是个全家桶默认勾选的东西能装出好几个 G。针对 VS2017 MSVC 的使用场景我一般这样勾必装Qt 5.14.2下的MSVC 2017 64-bit主用如果项目需要 32 位再加MSVC 2017 32-bit。Qt Debug Information Files——只在需要调试进 Qt 源码内部时才需要体积不小但排查崩溃时很有用。装不装看你有没有要打断点进 QWidget 内部的需求。Qt Creator很多人觉得用 VS 就不需要 Creator 了我建议留着因为在 Creator 里看.ui的实时预览、跑 qmake 检查环境变量、快速验证一段 Qt 代码是否正常都比在 VS 里折腾快。按需Qt Charts、Qt Data Visualization做数据可视化的项目要。Qt WebEngine嵌入浏览器内核的项目要注意它体积巨大而且 Windows 上基本只有 64 位预编译可用。Qt Virtual Keyboard嵌入式触屏项目常见。Sources想阅读 Qt 源码、或者要自己编译某个模块时勾上。MinGW 7.3.0如果你同时想用 MinGW 工具链做对比测试就勾纯 MSVC 环境可以不装能省一个 G 左右。不用装UWP、Android相关组件除非你真做那类项目。Qt Installer Framework做安装包的时候再说。3.2 安装路径、PATH 与多版本共存安装路径我强烈建议不要带空格、不要带中文像是D:\Qt\Qt5.14.2这种就很好。默认的C:\Qt也行但如果你打算同时装多个 Qt 版本5.12.10 和 5.14.2 共存是很常见的用一个统一的根目录、每个版本一个子目录管理起来最清楚D:\Qt\ Qt5.12.10\ 5.12.10\msvc2017_64\bin\qmake.exe Qt5.14.2\ 5.14.2\msvc2017_64\bin\qmake.exe注意那个多出来的一层版本号目录这是安装器自己的结构别觉得奇怪。关于 PATH不要把两个 Qt 版本的 bin 同时塞进系统 PATH。Qt 的 DLL 名字在不同小版本之间是一样的Qt5Core.dllPATH 里先找到哪个就用哪个很容易出现我明明编译的是 5.14运行起来加载的是 5.12 的 DLL这种诡异情况。我的做法是系统 PATH 里不放 Qt需要的时候靠 Qt VS Tools 在调试会话里注入或者用脚本临时设置。打包发布时用 windeployqt 把依赖拷到 exe 旁边也就不依赖 PATH 了。3.3 用 qmake -v 做一次最小验证装完之后别急着开 VS先在命令行做一次最小验证D:\Qt\Qt5.14.2\5.14.2\msvc2017_64\bin\qmake.exe -v正常输出会告诉你 qmake 用的是哪个版本的 Qt、以及它对应的编译器是 MSVC 的哪一代。这一行输出是你后面配 Qt VS Tools 时要填路径的直接依据务必确认路径里的msvc2017_64跟你工程的目标平台一致。如果这里报找不到某些 DLL说明安装不完整先解决这一步再往下走。验证完还可以顺手跑一次qmake -query输出里会有QT_INSTALL_PREFIX、QT_INSTALL_BINS、QT_INSTALL_HEADERS等路径。以后遇到头文件找不到的报错先看 qmake 报的这些路径是不是你期望的位置能省很多排查时间。4. Qt VS Tools插件版本、安装方式与 Qt Versions 配置4.1 版本对应关系为什么别盲目装最新Qt VS Tools老版本里叫 Qt5Package、Qt VS Add-in是让 VS 认识 Qt 工程的关键。它的版本和 VS 版本之间存在对应关系越新的插件版本对 VS2017 的支持越弱这不奇怪毕竟 VS2017 已经很老了官方把精力放在 VS2019/2022 上是正常的。所以你在 Qt 官方下载页的Qt Visual Studio Tools区域里会看到一长串.vsix文件文件名里通常带着msvc2017、msvc2019、msvc2022这样的标识。我的实操建议是先看文件名里带 msvc2017 的那几个再用 2.4.x 或 2.5.x 这两个大版本。这两个版本在我手上过 VS2017 是最稳的向导、Qt Versions 配置、.ui编辑、moc 自动生成全都正常。如果你装了明显更新的版本可能会遇到安装时报兼容性警告、装完菜单项不出现、或者工程属性页里 Qt 相关的选项卡直接消失。热词里VS2017 Qt 5.12.10 插件这个搜索大概率也是同一个问题——大家在找哪个版本的 Qt VS Tools 能装在 VS2017 上。答案的思路是一样的先按 VS 版本筛再按需选较新的稳定版。4.2 两种安装方式与安装后的确认动作安装方式有两种我都用过方式一VS 内扩展市场。打开 VS2017工具 → 扩展和更新 → 联机 → 搜索 Qt找到 Qt Visual Studio Tools 安装。优点是版本自动匹配缺点是内网环境打不开市场而且推荐给你的版本可能已经不支持 VS2017。方式二手动装 vsix。从 Qt 官网下载对应的.vsix关闭所有 VS 进程双击安装。如果双击没反应或者被识别成别的 VS 版本用命令行装C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VSIXInstaller.exe qt-vsaddin-msvc2017-2.4.3.vsix注意路径要按你实际的 VS 版本Community / Professional / Enterprise改。装完之后一定要重启 VS而且要看菜单栏有没有多出Qt VS Tools这一项。没有这一项后面所有配置都无从谈起先解决它。这里插一个排查点如果同时装了多个 VS 版本.vsix可能会被装到多个实例上而 Qt VS Tools 的 Qt 版本列表是按用户账户保存的机器级配置但工程里选了哪个 Qt 版本是跟着工程文件走的。这会导致一个很典型的现象同事把工程发给你你打开后报 Theres no Qt version assigned to this project for platform x64原因是他工程里写的 Qt 版本名字是Qt5.14.2_msvc2017_64而你机器上没有这个名字的记录。解决办法就是你在自己的 Qt Versions 里新建一条名字完全一样的记录指向你本机的 qmake。4.3 Qt Versions 里那几栏到底填什么打开Qt VS Tools→Qt Versions老版本叫Qt Options你会看到一个列表和几个按钮。点 Add 新建一条Name名称这是给你自己看的但也是写进工程文件里的字符串。命名上我推荐带全信息比如Qt5.14.2_msvc2017_64一眼看出 Qt 版本、编译器代次、位数。别用Qt1test这种名字工程一多你会记不清。Path路径指到 qmake.exe 所在目录通常是...\msvc2017_64\bin。有的版本要求指到目录有的接受直接选 qmake 文件按界面提示来。默认版本Default列表里可以设一个默认新建工程时会自动用它。建议把最常用的那个设成默认。配好之后点击 OK回到工程上做一次绑定验证右键工程 →Qt Project Settings→ General 选项卡里的Qt Installation下拉框应该能看到你刚建的版本。把 Debug|x64 和 Release|x64 两个配置都确认一遍——这个设置是按平台/配置组合保存的只设了 Debug|x64切到 Release 就会报 no Qt version assigned。还有一点值得提醒如果你发现 Qt Installation 下拉框是空的别急着重装插件。先关掉 VS把%LOCALAPPDATA%\QtMsBuild这个目录删掉再打开 VS 让它重新释放一遍构建脚本。这个目录是 Qt VS Tools 存放 moc、uic、rcc 的 MSBuild targets 的地方插件升级、或者 Qt 版本换路径之后它经常缓存变味删掉重建能解决大半的诡异问题。这一招我从 2.x 用到现在的版本命中率非常高。5. 第一个工程从模板生成到跑通调试5.1 模板生成出来的东西都有什么配置好之后新建工程文件 → 新建 → 项目 → Visual C → Qt →Qt Widgets Application做 QML 项目就选Qt Quick Application。填名字、选路径向导会让你选需要哪些基础类勾上 Core / GUI / Widgets 就够了。生成出来的工程结构大致是这样的main.cpp包含QApplication的创建、主窗口的实例化与show()。mainwindow.h/mainwindow.cpp主窗口类头文件里有Q_OBJECT宏。mainwindow.ui界面描述文件XML 格式。.vcxproj/.slnVS 的工程和解决方案文件Qt 相关的属性会写进 vcxproj 里。第一件要做的事是在mainwindow.h里看到Q_OBJECT宏的状态。如果 VS 把它标成红色波浪线但编译能过那是 VAX 或者 IntelliSense 没解析到 Qt 的头文件属于显示问题不影响构建。真正的构建失败会以错误列表里的 C 开头或 LNK 开头的编号出现。5.2 Qt Project Settings 各选项卡在管什么Qt Project Settings 是这套工具链里最该花时间摸清楚的界面理解它之后百分之八十的莫名其妙都能自己定位General核心是 Qt Installation。这里选错了 Qt 版本后面的包含目录、库目录全都会指到错误的路径上。Qt Modules勾选你要用的 Qt 模块Core、Gui、Widgets、Network、Sql、Charts 等等。每勾一个模块链接器的附加依赖项里就会多出对应的库Debug 配置下是带 d 后缀的版本比如Qt5Cored.lib。这是新手最容易漏的地方代码里#include QtNetwork/QTcpSocket写得好好的编译过了链接报一堆未解析符号原因就是没勾 Network 模块。moc / uic / rcc 相关选项卡这些控制的是元对象编译器、界面编译器、资源编译器的参数比如额外的包含路径、命令行参数、输出目录。绝大多数项目保持默认即可只有在写自定义插件、或者有特殊的编译期宏时才需要动。关键是理解一件事这个界面改的不是某个开关而是它会把结果写进.vcxproj也就是说这些配置是可以提交到版本库、被团队共享的。理解这点之后你就能解释为什么我改了 Qt 版本同事拉下来还是老样子——他需要重新打开工程让 VS 读到新的 vcxproj。5.3 平台下拉框、PATH 与调试启动的关系VS 顶部的平台下拉框x86 / x64决定的是编译器生成的位数而 Qt Installation 是按这个平台分别配置的。这是配了 Qt 还是报 no Qt version assigned的头号原因。调试阶段还有一个隐形的便利用 VS 的 F5 启动时Qt VS Tools 会自动把 Qt 的 bin 目录加到调试进程的 PATH 里所以你能正常跑起来。但如果你去x64\Debug目录里直接双击那个 exe就会发现它找不到Qt5Cored.dll。这不是工程配置错了而是环境变量没设。理解这个区别很重要——很多人在这一步慌了以为工程有问题其实只是发布时要处理依赖。想验证也很简单把 exe 需要的几个 DLL 从 Qt 的 bin 目录拷到 exe 旁边再双击如果正常启动那就确认是 PATH 与依赖部署的问题不是构建问题。6. 报错对照表踩过的坑和它们的根因6.1 六类高频报错的现象、根因与修复下面这张表是我这些年攒下来的按出现频率排的。遇到问题先对号入座别一上来就重装插件。现象真实根因修复动作Theres no Qt version assigned to this project for platform x64当前平台/配置没绑定 Qt 版本或工程来自别人机器版本名对不上Qt Project Settings 里为该平台选 Qt 版本名字对不上就新建同名记录无法打开包括文件QtWidgets/QApplication包含目录没注入通常是 QtMsBuild targets 没加载确认 Qt Installation 生效删除%LOCALAPPDATA%\QtMsBuild重开 VSLNK1104无法打开文件Qt5Core.libQt Modules 没勾 Core或库目录指向另一个 Qt 版本或位数不匹配检查模块勾选、检查 Qt 版本路径里是 32 还是 64 位LNK2019无法解析的外部符号__imp_...工程与 Qt 的位数不一致debug 工程链了 release 库工具集混用统一平台位数统一 Debug/Release工具集统一 v141启动提示no Qt platform plugin could be initializedexe 同级缺少platforms\qwindows.dll从 Qt 的plugins\platforms拷贝或用 windeployqt提示缺少Qt5Cored.dll直接双击运行PATH 里没有 Qt 的 bin加 PATH或把依赖拷到 exe 旁边用这张表的时候有个技巧从最后一条现象往前推。比如LNK2019报的是某个QString相关的符号找不到那基本可以断定是位数或 Debug/Release 的问题因为你不会忘记勾 Core 模块不勾 Core连QApplication都找不到错误会更靠前。6.2 debug/release 混用引发的连锁反应这是我觉得最值得单独讲的一个坑。Qt 的官方 msvc 包同时提供 Debug 和 Release 两套库Qt5Cored.lib/Qt5Core.lib工程在 Debug 配置下会链接带 d 的那套。如果你在 Release 配置里手动加了一个来自 Debug 目录的库或者在 Debug 配置里加了一个 release 版本的第三方库症状通常是编译阶段一切正常链接阶段报一堆符号缺失或者链接通过运行到某个 Qt 容器操作时直接崩更隐蔽的是程序能跑但在退出时崩溃因为跨模块的内存分配和释放用了不同的堆。排查方法很土但有效打开项目属性的链接器 → 输入把附加依赖项完整看一遍凡是 Debug 配置里出现不带 d 的 Qt 库或者 Release 配置里出现带 d 的都是可疑对象。另外检查链接器 → 常规 → 附加库目录里有没有残留一个指向 Debug 目录的路径。Qt VS Tools 自动生成的依赖一般是对的出问题的往往是你后来手动添的那些。6.3 中文乱码、/utf-8 与高 DPI中文乱码这个坑跟 Qt 关系不大但和 MSVC 关系很大。MSVC 默认按系统本地代码页简中环境是 GBK解释没有 BOM 的源文件而 Qt5 在把窄字符串转成QString时按 UTF-8 处理。两边标准不一致结果就是界面上的中文变成一堆问号或者方块。三种解法我推荐第三种把源文件保存成UTF-8 带 BOMMSVC 看到 BOM 就知道按 UTF-8 解析。显式用QString::fromLocal8Bit(中文)在 GBK 源文件下能正常但换环境就崩。在项目属性 → C/C → 命令行里加/utf-8让编译器统一按 UTF-8 处理源文件和执行字符集。这个设置对一个团队来说最容易统一也是我在所有新工程里的默认动作。高 DPI 是另一个必踩的点。Qt5.14 在 4K 屏上默认可能界面糊或者控件尺寸不对需要在main()里、在构造QApplication之前设置QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication app(argc, argv);顺序写反了是不生效的这点很关键。Qt5.14 也支持用环境变量QT_ENABLE_HIGHDPI_SCALING1控制临时验证时比较方便。7. .ui、.qrc 与 mocVS 里这些文件是怎么被处理的7.1 .ui 文件在 VS 里的两种打开方式在 Qt Creator 里双击.ui就是设计器在 VS 里这事稍微绕。装了 Qt VS Tools 之后双击工程里的.ui文件通常会在 VS 内部以文档窗口的形式打开 Qt Designer 的界面可以拖控件、改属性、连信号槽。这条路能走通的前提是插件版本和 VS 版本匹配插件加载正常。如果双击打开的是 XML 文本或者报了无法加载设计器两个备选方案在文件上右键选打开方式找到Qt Designer安装 Qt 时附带的designer.exe在 Qt 的 bin 目录下。直接用 Qt Creator 打开这个.ui单独编辑保存后回到 VS 编译两边不会冲突。要理解的是.ui文件在构建时会被 uic 工具转成一个ui_xxx.h头文件一般生成在中间目录里你的mainwindow.cpp里#include ui_mainwindow.h用的就是它。所以改了.ui之后必须重新编译界面才会变有时候界面没更新是因为增量编译没识别到文件变化清理后重新生成就好。7.2 .qrc 资源与 rcc 的生成时机.qrc是 Qt 的资源描述文件用来把图片、图标、翻译文件、样式表打包进 exe。它的处理链是rcc 把.qrc里列出的文件编译成 C 源码再参与链接。这个过程对使用者是透明的但有两个需要注意的点第一加入.qrc的文件在工程里是外部文件VS 的解决方案资源管理器里可能看不到它们除非手动加到筛选器里但它们在编译时会被读取。路径写错了尤其是相对路径会报找不到文件而且报错信息有时候不太直观。第二资源文件改动后同样要重新编译。如果你替换了一张图片界面上还是旧的先确认是不是资源没重新生成。另外.qrc里路径写错大小写在 Windows 上可能侥幸能过文件系统不区分大小写但换到别的平台就炸了所以从一开始就严格按实际大小写写。7.3 QtMsBuild 缓存与增量编译的怪现象前面提过%LOCALAPPDATA%\QtMsBuild这个目录这里展开说下它为什么重要。Qt VS Tools 2.x 之后moc/uic/rcc 的执行不是硬编码在插件里的而是通过一组 MSBuild targets 文件驱动的。VS 在构建工程时会加载这些 targets判断哪些文件需要生成、生成到哪里、依赖关系是什么。由此带来几类典型怪现象改了头文件里的Q_OBJECT相关信号槽编译却不报错也不生效moc 的依赖判断没跟上清理后重建。报 QtMsBuild not found 或某个 targets 文件缺失插件升级或路径变更后缓存的旧 targets 失效。构建速度突然变慢每次都在重新生成 moc 文件targets 里的时间戳判断被破坏了。对应处理就一条关 VS删%LOCALAPPDATA%\QtMsBuild重开让它重新释放。我一般还会顺手把工程的x64\Debug中间目录删掉做一次干净的完整重建确认问题是否真的消失。这一套下来能解决九成的玄学构建问题。8. 打包发出去windeployqt 与缺 DLL 的老问题8.1 一条能用的 windeployqt 命令调试跑通只是第一步把程序给别人用的时候依赖得自己带上。Qt 提供了windeployqt.exe位于 Qt 的 bin 目录下它会扫描你的 exe把需要的 Qt DLL、插件、翻译文件拷到 exe 旁边。我最常用的形式是这样D:\Qt\Qt5.14.2\5.14.2\msvc2017_64\bin\windeployqt.exe ^ --release ^ --no-translations ^ --no-system-d3d-compiler ^ --no-opengl-sw ^ D:\build\MyApp\x64\Release\MyApp.exe几个参数说一下取舍逻辑。--release明确告诉它是 release 版本避免它误判后拷了带 d 的调试 DLL那些 DLL 在没装 VS 的机器上根本跑不起来而且体积大一倍。--no-translations和--no-system-d3d-compiler、--no-opengl-sw是缩小体积用的如果你的程序不需要多语言、不需要 Qt 自带的 D3D 编译器和 OpenGL 软件渲染回退关掉它们能省不少空间。QML 项目还要额外加--qmldir指向你的 qml 源码目录让它扫描出实际用的 QML 模块。打包完成之后一定要在一台没装 Qt 也没装 VS 的干净机器上测一遍。这一步别省我见过太多次开发机跑得好好的客户机器上白屏。8.2 常见能调试不能双击运行的原因这类问题的根因基本可以归成四类按概率排缺platforms\qwindows.dll。Qt 的窗口系统是通过插件加载的缺了它就报no Qt platform plugin could be initialized。注意目录结构必须是exe所在目录\platforms\qwindows.dll直接放到 exe 旁边是不行的。缺 C 运行库。目标机器没装对应的 VC 运行库需要一起带上或者让用户装。VS2017 对应的运行库版本要和你编译时用的一致。缺图片格式插件。用了 PNG、JPEG 之外的特殊格式或者用了 SVG需要imageformats目录下的对应插件。加载了错误的 DLL。目标机器的 PATH 里有另一个版本的同名 Qt DLL被优先加载了。这个问题最气人因为表现是随机崩溃而不是启动失败。解决办法是把依赖都放在 exe 同级目录利用 Windows 的 DLL 搜索顺序exe 所在目录优先于 PATH。另外还有一个容易被忽略的点如果你在代码里用了QSplashScreen显示启动画面或者用了某些需要在QApplication之前创建的对象顺序错了会在 release 版本下崩溃而在 debug 下正常因为 debug 版本的容错性更强。这类问题排查时把 release 版本的崩溃信息可以用qInstallMessageHandler记录或者看 Windows 事件查看器里的模块名当成第一手线索。最后分享两个我一直在用的习惯。一个是给每个工程写一份环境卡就放在仓库根目录的 README 里写清楚Qt 版本号、msvc 包名、VS 版本与工具集、SDK 版本、需要手动勾选的模块和 /utf-8 这类编译选项。新人入职或者换机器的时候照着卡片走一遍能省掉大半天试错。另一个是把 Qt Versions 的命名规范固化下来全团队用同一套命名比如Qt版本_msvc代次_位数这样别人工程里的 Qt 版本引用在你机器上一定能找到同名记录不会再被 no Qt version assigned 卡住。这两个习惯看起来是流程上的小事但在多人协作里它们比任何一条编译参数都值钱。