1. 为什么我最终选择了Visual Studio + Qt这套组合
先说个我这几年的实际感受:Windows桌面开发圈子里面,很多人一提到Qt,脑子里第一时间想到的就是Qt Creator——官方IDE、界面清爽、跨平台支持好。但我个人从Qt 5.9时代开始,就把主力开发环境换成了Visual Studio + Qt的组合,一直用到现在。
原因其实很朴素:我是一个重度依赖调试器、依赖代码补全、依赖快捷键的开发者,Visual Studio这套IDE在Windows上打磨了二十多年,无论是断点调试、内存窗口、调用堆栈分析,还是对CMake / MSBuild工程体系的支持,都比Qt Creator成熟得多。尤其是工程一旦变大,项目文件夹几十上百个,Qt Creator的文件查找和代码导航会显得吃力,而VS的Solution + Project结构在管理大型C++工程时逻辑感更强。
这套组合能解决什么问题?简单说:把Qt强大的跨平台UI框架和VS强大的Windows原生开发体验整合在一起,让你既能写Qt Widgets界面,也能无缝调用Windows API、使用MSVC编译优化,同时在调试阶段获得远超Qt Creator的体验。
适合谁来参考?如果你是这类情况,我觉得可以继续往下读:
- 在Windows上做Qt桌面应用,但对Qt Creator的调试体验不满意;
- 公司或团队已有的C++工程体系是基于Visual Studio + MSBuild的,你要把Qt模块嵌入进去;
- 想用上VS的扩展生态、重构工具、性能分析器,又不想放弃Qt的跨平台能力;
- 被VS Code的各种配置折腾得够呛,想回到“装好就能写”的IDE。
那么接下来,我从环境搭建开始,把Visual Studio + Qt这套组合从配置到调试、从编译到发布的完整链路都梳理一遍,也会穿插一些我自己踩过的坑。
2. Visual Studio + Qt 组合的核心选型思路
2.1 为什么不建议直接一路默认安装
很多新手拿到Qt在线安装包之后,咔咔一路下一步,安装了一堆根本用不上的组件。等打开Visual Studio开始写Qt代码的时候,各种“unable to find suitable visual studio toolchain”和“unknown module(s) in qt”就冒出来了。
问题根源在于:Qt的安装包和Visual Studio的C++工作负载不是一回事,它们之间要靠编译器的位数和版本去匹配。
Qt本身不是“一个IDE装好就万事大吉”的框架,它是一套二进制库,你在Windows上用的MSVC版本的Qt库,必须和VS里C++工具集的版本对得上。比如你装的Qt是msvc2019_64,那VS里最好用的是2019或2022的工具集,x64平台,才能顺利编译链接。
我后面会专门讲怎么配,但这里先记住一个总原则:Qt编译器和Visual Studio编译器必须同源同位数,这是整套组合不炸的前提。
2.2 用MSVC版本的Qt,而不是MinGW版的Qt
Qt官方在线安装包里,Windows平台通常给你两类编译器选项:
- MinGW:GCC系的编译器,和Qt Creator搭配比较顺手,但Visual Studio 根本不认识MinGW编出来的库,没法直接用;
- MSVC:微软的C++编译器,分msvc2019_64、msvc2022_64等变体,这才是Visual Studio能吃进去的版本。
如果你计划用Visual Studio开发Qt,一定要选MSVC版本的Qt库。MinGW版就留给纯Qt Creator的用户用,不要混。
按我个人经验,现在比较稳定的搭配是:
| 组件 | 推荐版本 |
|---|---|
| Qt | Qt 5.15.2 LTS(支持离线安装,稳定) |
| Visual Studio | Visual Studio 2022 Community,免费 |
| Qt VS Tools 插件 | 3.0.2 以上 |
| Qt安装组件 | 勾选你要用的编译器二进制 + Sources |
不要觉得Qt 5.15.2已经老了,其实在很多嵌入式、工控、桌面软件项目里,Qt 5.15.2依然是“LTS中的王者”,稳定性非常好。Qt 6 虽然新,但很多老项目迁移成本高,Visual Studio插件兼容链路也没有Qt 5完善。
2.3 关于VS版本的细节点
Visual Studio 2022这个版本本质上是64位的IDE,比之前2019的32位外壳强很多,打开大型解决方案的时候明显更快,内存占用也更合理。
但要注意:装了VS 2022不代表就能编译C++。你必须在安装器里勾选“使用C++的桌面开发”工作负载,里面才会带上MSVC编译器、Windows SDK、CMake工具等。
所以我建议的完整安装步骤是:
- 打开Visual Studio Installer;
- 选择Visual Studio 2022 Community;
- 勾选“使用C++的桌面开发”;
- 右侧安装详细信息里,确保“Windows 11 SDK”(或Windows 10 SDK)被勾选;
- 顺手勾上“适用于Windows的C++ CMake工具”,万一后面用到CMake工程不抓瞎;
- 安装。
装完之后可以在开始菜单里找到“Developer PowerShell for VS 2022”这种环境,方便以后用命令行编译Qt项目的时候自动加载环境变量。
3. Qt 环境搭建和 Visual Studio 插件的配置细节
3.1 Qt安装环节别选错组件
在安装Qt时,我强烈建议不要直接点“Next到底”,一定要展开Qt 5.15.2这个节点,把MSVC 2019 64-bit这个子项勾上。如果你想后期自己编译补丁、编第三方库,还需要把Sources组件勾上。
Qt安装器里的组件选择其实直接影响后面能不能用VS编译工程。很多人装Qt时只勾了“Qt Charts”、“Qt WebEngine”这种,漏掉了基础的msvc库,结果VS里一编译就报找不到头文件,排查半天。
我整理一下最少组件清单:
- Qt 5.15.2 > MSVC 2019 64-bit(必备);
- Qt 5.15.2 > Sources(强烈建议勾上,编译QSerialPort这样的附加模块要用);
- Developer and Designer Tools > Qt Creator(保留);
- Developer and Designer Tools > Debugging Tools(看情况,一般建议勾上);
- 如果你在别的机器上装了不同组件组合,那就要检查是否和VS版本匹配。
安装路径不要有中文和空格,比如放在D:\Qt\5.15.2\msvc2019_64。这个习惯能帮你避免一堆莫名其妙编译路径报错。
3.2 Qt VS Tools 插件:桥接的关键
Qt官方维护了一个Visual Studio扩展插件,叫“Qt VS Tools”,这是把Qt固件集成进VS的桥梁。没有它,你在VS里创建Qt项目会比较痛苦,因为VS本身不原生识别.pro文件和.ui文件。
安装方法:
- 打开Visual Studio 2022,菜单栏“扩展 > 管理扩展”;
- 右上角搜索框输入“Qt”;
- 找到“Qt Visual Studio Tools”,安装,重启VS;
- 菜单栏出现“扩展 > Qt VS Tools”,表示插件生效。
如果在线扩展商店连不上,你还可以去Qt官方下载离线vsix包手动安装。离线包的好处是单位内网环境也能装。
3.3 配置Qt版本路径
安装完插件后,第一件事是在VS里指定Qt安装目录。
打开“扩展 > Qt VS Tools > Qt Versions”,添加一条路径,指向刚才安装的Qt msvc目录,比如:
D:\Qt\5.15.2\msvc2019_64这里我特别提醒一句:路径里一定要带msvc字段,别手滑选成MinGW目录。选错之后在VS里新建Qt项目时会直接报“compiler not recognized”之类的错误。
同时,把这条版本路径设成默认。
3.4 用Qt VS Tools 创建一个新工程
配置好之后,就可以用VS来创建Qt项目了。
- 文件 > 新建 > 项目;
- 搜索Qt,列表里会出现Qt Widgets Application、Qt Console Application等模板;
- 选择Qt Widgets Application;
- 填写项目名、位置;
- 确认模块选择(Widgets、Core、Gui是基础);
- 项目生成后,会看到.ui文件、.cpp、.h自动列出来。
VS会把Qt项目转成一个.vcxproj工程文件,背后实际是用MSBuild来调Qt的moc、uic、rcc工具。所以你在编译时看到moc生成代码的过程,其实是插件替你把qmake那套活儿接管了。
第一次编译可能稍慢,因为要跑moc和uic生成一堆中间代码。之后增量编译就很快了。
3.5 小技巧:把解决方法目录整理好
在VS里开发Qt项目,一个项目下面可能有大量.moc文件生成在$(Configuration)目录里。如果你发现导航目录乱糟糟,建议在解决方案上右键,点击“文件系统”或者“Class View”来浏览,而不是看传统的“所有文件”。
VS的Class View(类视图)对Qt项目特别友好,能直接列出QObject的子类、信号、槽,查看继承结构比Qt Creator直观很多。
4. 用Visual Studio实际操作Qt项目的核心环节
4.1 信号槽和Q_OBJECT宏的坑
用VS写Qt,最容易踩的坑是:往一个类里加了Q_OBJECT宏,然后连接信号槽,编译报各种“未定义成员函数”或者连接后不响应。
根源在于moc工具重新生成了代码,但VS的项目依赖没有自动更新。
我常用的两种办法:
- 方法一:右键出问题的.h文件,在属性里手动触发一下自定义生成工具,把moc结果重新生成;
- 方法二:直接清理解决方案再重新生成,最省事。
如果你用的是Qt VS Tools插件,一般在保存文件后,VCXProj的构建规则会自动处理moc。但偶尔也会抽风,我碰到过好多次,所以第一反应千万不要去删obj文件,先清理再生成。
4.2 调试Qt程序,体验确实好
用Visual Studio调试Qt程序,最舒服的是变量监视窗口和断点条件设置。你可以直接把QString变量拖进监视窗口,能展开内部数据,就不需要“右键 > 添加QString可视化工具”这种操作。
这里我分享一个我常驻的断点表达式写法:
strValue.isEmpty()用来在循环里快速定位哪一次strValue是空的。VS里的条件断点非常好用,Qt Creator也有,但在VS里设置条件断点、命中计数、线程过滤都比Qt Creator顺手。
另外,调试Qt Widgets程序时,如果界面渲染出问题,可以在VS的“GPU调试”或者“图形诊断”里抓帧,这对写自绘控件和复杂场景特别有帮助,Qt Creator在这方面几乎没有对应的方案。
4.3 Qt SerialPort 模块为何偶尔在VS里失踪
热搜词里好多人搜“unknown module(s) in qt: serialport”,这个问题在微软VS下更容易出现。
原因很直白:Qt官方在线安装器默认提供的MSVC预编译二进制,并没有包含 Qt SerialPort 这个模块。Qt SerialPort 模块的源码是放在 Qt 源码包里的,但你需要自己编译出来。
所以解决办法不是升级VS,也不是重装Qt,而是先确认你有没有Sources组件,然后手动编译这个模块。
步骤大概是这样:
- 打开“Developer Command Prompt for VS 2022”;
- cd到Qt源码目录下的qtserialport文件夹;
- 执行:
qmake nmake nmake install - 编译完成后,把生成的serialport库文件拷贝到Qt的lib和include目录里。
但如果你是Visual Studio下开发,还有更顺滑的方法:直接在你的.vcxproj里单独引用qtserialport模块的源码或预编译库,避免动Qt主安装目录。
另外,如果你的工程是通过QT += serialport这种qmake语法来引用模块的,一定要检查是不是拼写错了,Qt模块区分大小写,全部小写才对。
4.4 读写JSON:在VS里写Qt代码的优势
Qt的JSON支持其实非常好用,QJsonDocument、QJsonObject这套API十几年来变化不大,稳定得很。我在VS里开发时,最喜欢用它的JSON编辑器插件来格式化测试数据,同时配合Qt的QJsonDocument::fromJson来在调试时快速查看解析结果。
一个日常开发常见场景:读取配置文件。
QFile file("config.json"); if (!file.open(QIODevice::ReadOnly)) { qWarning() << "open config failed"; return; } QByteArray data = file.readAll(); QJsonDocument doc = QJsonDocument::fromJson(data); QJsonObject obj = doc.object(); QString path = obj.value("outputPath").toString();在VS里调试的时候,直接把obj添加进监视窗,可以看到整个JSON树结构,非常直观。Qt Creator也有类似功能,但VS的快速监视窗快捷键是Shift+F9,比Creator顺手得多。
4.5 在VS里获取文件信息、处理路径
Qt 处理文件信息主要靠QFileInfo,这个类在VS里配合代码补全用起来很舒服。比如获取文件大小、后缀、最后修改时间:
QFileInfo info(filePath); qDebug() << info.size() << info.suffix() << info.lastModified().toString();这里有个经验要分享:VS的IntelliSense偶尔会因为Qt头文件太多而变卡,如果发现补全突然延迟严重,可以试试菜单“工具 > 选项 > 文本编辑器 > C/C++ > 高级”,把“禁用自动更新”开启,或者调整“最大缓存翻译单元数”,会有明显改善。
5. Qt绘图效率对比:到底在VS里开发什么场景
5.1 QPainter绘图和Qt Quick场景的选型
最近热搜词里“qt绘图效率比较”出现频率很高。我在这里顺便讲一下用VS + Qt开发时,不同绘图技术的选型思路。
Qt主要绘图路径有三条:
- QPainter直接绘制:适合相对简单的自定义控件、图表、标注等,优点是好理解、好调试;
- QGraphicsView / QGraphicsScene:适合图元多、需要交互、需要碰撞检测的场景;
- Qt Quick + Scene Graph:适合高刷新率、流畅动画、移动端风格界面。
在Visual Studio里,这三条路径开发体验差距不大。QPainter绘图因为逻辑都写在C++里,VS的调试对你帮助巨大:你可以随时查看QPainter的当前状态、绘制路径上的点集坐标,按F10单步跟踪每个绘制步骤。
5.2 拿一个实际绘制示例来分析
我写过一个小工具,需要在界面上绘制实时曲线。最初用的是QPainter绘制,每来一个数据点就update(),在数据点不多时(几百个)完全没问题。但数据量飙到几万个点之后,CPU占用明显上去了,开始掉帧。
用VS的性能分析器(Alt+F2)跑了一轮,发现瓶颈在QPainter::drawPolyline调用上,其实每一次repaint都会把整条折线全部重绘,数据太多必然慢。
优化方案是:
- 用QGraphicsView + 自定义QGraphicsItem,只对变化的数据区域局部更新;
- 或者把数据点按比例抽稀,只绘制屏幕上可见范围的数据。
这个排查过程如果你用Qt Creator,大概要看日志靠猜;换到VS之后,性能分析器直接给我指出了热点函数,问题一目了然。
5.3 Qt Quick项目在VS里的配置
如果你开发的是QML / Qt Quick界面,也可以挂在VS里管理。Qt VS Tools插件同样支持创建Qt Quick项目。
调试QML时,在VS菜单里选“调试 > 附加到进程...”,选中你的应用进程,然后打开qml文件打断点即可。注意QML调试器需要在项目里开启QML调试端口,默认是35686之类的,插件会自动配好。
我个人经验是:QML界面逻辑复杂时,多花点时间把JS部分抽出来单独调试,会轻松很多。VS里的JavaScript调试模块也能用上,比在Qt Creator里一头扎进QML引擎里查问题要容易。
6. 发布与部署:别再到处找dll了
6.1 用windeployqt自动收集运行库
Qt项目在VS里编译出exe之后,直接拷到别的机器十有八九跑不起来,因为缺少Qt运行库。常规做法是使用Qt自带的windeployqt工具。
路径一般在:
D:\Qt\5.15.2\msvc2019_64\bin\windeployqt.exe打开VS的开发者命令行,cd到exe所在目录:
windeployqt myapp.exe它会自动把需要的Qt DLL、平台插件、样式插件全部拷贝到exe旁边。这个方法比手动从Qt安装目录翻dll可靠得多,而且能避免漏掉某个特定插件。
有个小细节:如果你用到了Qt SerialPort这类自己编译过的模块,windeployqt可能不会自动识别。这时候你需要手动把它编译出来的serialport.dll也拷贝到发布目录下。
6.2 发布时注意release构建配置
在VS里,默认的构建模式是Debug,但发布给用户一定要用Release,且链接器优化按照Release的默认配置来。
编译之前,在工具栏的解决方案配置下拉菜单里,把“Debug”改成“Release”,平台选“x64”,然后重新生成解决方案。
注意:Debug版本的Qt库和Release版本的Qt库不能混用。如果你发现自己Release版跑起来一会儿崩溃,一会儿中文乱码,先检查是不是链接了Debug版的Qt库。
6.3 好用的部署方式:NuGet包
如果你不想在业务机器上安装完整的Qt环境,还有一种更现代化的方式:用NuGet引入Qt库。Visual Studio原生支持NuGet包管理器,社区里有第三方把Qt的MSVC库打包成了NuGet包。
右键项目 > 管理NuGet程序包,搜索Qt,可以找到一些封装好的包。
个人建议是:个人练手项目完全可以这么玩,非常省事;但公司级商业项目,还是老老实实用Qt官方安装包 + windeployqt,因为NuGet包的来源和授权不够透明,出了问题排查成本更高。
7. 常见问题和排查技巧实录
7.1 unknown module(s) in qt 的完整排查路径
这个报错太经典了,尤其是serialport。我每次遇到都会按下面这个顺序排查:
- 检查.pro文件拼写:
QT += serialport,全部小写,拼写错了直接报; - 检查qmake版本:确保用的qmake是MSVC版本,不是MinGW版本;
- 检查模块是否编译:如果qt安装目录下的
lib和include中没有对应的库和头文件,那就是缺模块编译; - 检查构建套件:在VS里选的项目属性里,确保“Qt Installation”字段指向的路径包含对应模块的include目录。
7.2 Visual Studio连接不到编译工具链
热词里有“unable to find suitable visual studio toolchain”。这个一般是装了VS但没装C++工作负载,或者VS装完了没有重启系统导致环境变量没生效。
排查方式:
- 打开“控制面板 > 程序 > Visual Studio Installer”,点“修改”,确认“使用C++的桌面开发”是勾选状态;
- 打开一个普通cmd,输入cl,看能不能找到编译器;
- 如果找不到,说明环境变量没配置。用“Developer PowerShell for VS 2022”指定环境后再编译即可。
7.3 Qt项目在VS里编译通过了,双击打开却没反应
这是播种率相当高的问题,常见原因有三个:
- 窗口程序主线程返回了,事件循环没起来,检查main里的
app.exec(); - 缺少动态库导致进程秒退,用Dependency Walker或直接跑一下命令行看输出;
- 有中文路径导致资源加载失败,把项目路径改纯英文。
7.4 快捷键和命令行编译
如果你习惯了VS的热键,开发Qt项目会如鱼得水。我最常用的几个:
Ctrl+K, Ctrl+S代码片段;F9设置断点;F5调试;Ctrl+Shift+B仅生成;Ctrl+Alt+Q(如果装了Qt插件)快速查找信号槽定义。
命令行编译场景下,VS和Qt配合也不赖。用vsdevcmd打开环境之后,可以在命令行执行:
cmake -S . -B build -DCMAKE_PREFIX_PATH=D:/Qt/5.15.2/msvc2019_64 cmake --build build --config Release这种方式适合CI/CD构建机器,比如GitLab Runner或GitHub Actions跑Windows构建任务时特别好用,不需要依赖VS图形界面。
8. 提升开发效率的几个独门经验
最后分享几个我用Visual Studio开发Qt这些年摸索出来的小经验。
第一,在VS里配合使用Visual Assist或ReSharper C++这类辅助插件时,Qt代码的补全和重构体验提升非常大。Resharper C++对Qt有专门支持,能识别信号槽、Q_PROPERTY、emit等关键字,重命名一个信号时,所有连接它的槽都会同步改名,这在Qt Creator里反而没这么顺手。
第二,把Qt的头文件目录加到VS的“包含目录”之后,第一次索引会很慢。建议在“工具 > 选项 > 文本编辑器 > C/C++ > 高级”里,把“强制无外部头文件模式”设为True,或者手动排除Qt的Tests和Examples目录,IntelliSense会快很多。
第三,项目里如果同时用Qt和微软自己的库,要特别留意Windows头文件和Qt头文件的包含顺序。最常见的坑是两个库都定义了slots、signals这类宏,放开之后冲突。我的经验是:先包含Qt头文件,再用#include <windows.h>,如果仍然冲突,就在包含Windows头文件前定义:
#define WIN32_LEAN_AND_MEAN #define NOGDI这样一般能绕开大部分宏冲突。
第四,关于Qt更新版本的事情。不要一有新版本就急着换。Qt 5.15.2在我看来目前更像生产环境保守首选。如果你要折腾Qt 6,尽量等到Qt 6.x的某个LTS版本出来后稳定一段时间再迁移,毕竟在Visual Studio里切换Qt版本只是改一个路径配置,但工程里潜在的API改动才是要花时间的地方。
第五,关于多人协作。Visual Studio的.vcxproj本身是文本格式,适合放Git里做diff。第一次把Qt项目加入版本控制时,建议把生成的.vs目录、x64、Debug、Release这些文件夹加进.gitignore,避免一起提交造成冲突。
我自己因为从Qt Creator迁移到VS,浪费过不少时间在处理moc生成文件、路径匹配这类琐碎问题上。现在回头再看,其实无非就是版本、位数、路径三个核心点抓住,后面就顺了。如果你也正在走这条迁移路,希望这篇文章能帮你少踩几个坑。