前几天有人私信我说机器上装的是 Visual Studio 2015老师又要求交一个带图形界面的 C 小作业问我能不能用 VS2015 配 Qt 来做。当然能而且 VS2015 Qt 这套组合是国内很多老项目、教材和实验课上绕不开的一条路。这篇就把从零跑通图形化 Hello World 的每一步讲透版本怎么配、插件怎么装、项目怎么建、报错怎么治最后再顺手做一个能输入名字的小交互。适合刚接触 Qt或者平时只在命令行里写过 C 的朋友。1. 版本搭配先过关VS2015该配哪个Qt1.1 先搞懂Qt安装包的命名密码很多人一上来就栽在下载环节去 Qt 官网看到一堆目录msvc2015、msvc2017、mingw73_64……直接懵了。其实 Qt 官方安装包的名字已经把答案写脸上了msvc2015表示它用 VS2015 的编译器MSVC v140 工具集编译msvc2015_64表示 64 位版本mingw53_32这种带 MinGW 的是另一套编译器体系跟 VS 是两路人。Qt 是靠底层库分发的你用msvc2015编译出来的库配合 VS2015 的 v140 运行时兼容性才是最稳的。如果你强行装一个msvc2017的 Qt 包再用 VS2015 去链接最常见的后果就是编译阶段报一堆头文件缺失、链接阶段报LNK2019或者即使编译过了运行时弹 0xc000007b非常劝退。1.2 我的推荐组合与理由VS2015 对应的 Qt 版本我一般推荐Qt 5.11.2或者Qt 5.9LTS 长期版。原因很简单这两个版本是官方最后一波还提供msvc2015预编译包的版本。到 Qt 5.12 以后官方预编译包的主打编译器换成了 msvc2017VS2015 用户就得自己折腾源码编译那个复杂度对新手来说完全是灾难。另外提醒一句如果选的是 MinGW 版本就要搭配 Qt Creator 使用而不是 VS。所以用 VS2015 做开发安装 Qt 时一定要勾选 MSVC 系列的包别顺手勾了 MinGW装完发现模板里面啥都没有又得回头折腾。如果你只是练手32 位和 64 位怎么选我的建议是第一次做就先装 32 位msvc2015VS 里用默认的 Win32 平台少一层位数不匹配的烦恼。64 位后面会了再补也不迟。2. 安装与配置组件勾选、插件注册、Qt Versions指路2.1 Qt在线安装器里到底要勾什么安装 Qt 时我建议用离线安装包省去注册账号和网络的等待。安装路径建议用D:\Qt这种短路径尽量不要带空格和中文比如C:\Program Files (x86)\Qt。虽然 Qt 也能处理但后面你用命令行工具、拼环境变量路径的时候空格经常会给你整出意想不到的幺蛾子。进入组件选择页面之后展开Qt 5.11.2这一项勾上msvc2015或msvc2015_64看你前面决定装哪个。下面那一长串 Qt Charts、Qt 3D、Qt WebEngine 之类Hello World 阶段一律不勾装了纯属占硬盘。等你真的需要某个模块以后单独维护也是可以的。工具链那块除非你想顺便试试 Qt Creator否则不用额外装。装完后你会在D:\Qt\5.11.2\msvc2015_64下面看到 include、lib、bin 这些目录这就算成了。这里要习惯性地做一个动作设置环境变量。新建QTDIR值填D:\Qt\5.11.2\msvc2015_64把%QTDIR%\bin追加到Path变量里。这步不是必须但做了之后后面在命令行里跑windeployqt、或者排查“找不到 Qt5Widgets.dll”时会省事很多。2.2 VS2015侧的Qt插件与Qt Versions设置VS 本身不认识 Qt它俩之间需要一个插件来桥接。VS2015 上一般装的是 Qt Visual Studio Tools老一些的资料里叫 Qt Add-in。打开 VS2015进工具 - 扩展和更新 - 联机搜索 “Qt Visual Studio Tools”下载安装后重启 VS。装完插件菜单栏会多出一个Qt VS Tools或老版本的Qt菜单。进去找到Qt VS Tools - Qt Options左侧选Qt Versions点Add按钮名称随便填路径选到D:\Qt\5.11.2\msvc2015_64。填完设成默认。这步千万别跳过。插件靠这个路径去定位头文件、库文件还要调用moc、uic、windeployqt这些 Qt 自带工具。路径填错或者没填后面新建工程后一编译就是一堆“工具找不到”的错。3. 第一次新建Qt Widgets项目每个人的第一个带界面的C程序3.1 选对模板之后项目里这几个文件是干嘛的打开 VS2015文件 - 新建 - 项目左侧选 Visual C如果插件正常你会看到Qt Widgets Application旧版插件可能叫Qt Application。给项目起名HelloWorld点确定。系统会生成一个 Qt 项目核心文件就这几样HelloWorld.proqmake 工程文件以后你想脱离 VS、单纯用命令行构建它就有用了main.cpp整个程序的入口创建应用对象和主窗口进入事件循环mainwindow.h/mainwindow.cpp主窗口类的声明和实现mainwindow.ui用 Qt Designer 可视编辑的界面文件。新手容易犯的错是把mainwindow.ui当普通文本乱改或者去翻生成的ui_mainwindow.h。这个文件是在编译前由uic工具根据.ui自动生成的你改它没有任何意义下次重新生成又会覆盖。main.cpp 默认长这样先混个脸熟#include mainwindow.h #include QApplication int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }a.exec()是事件循环别问为什么窗口能一直挂着不退出就是这个函数在持续接收鼠标、键盘、绘制等消息。这是 Qt 应用生命的核心。3.2 在Qt Designer里拖出按钮和标签双击项目里的mainwindow.ui会打开 Qt Designer 的可视化编辑界面。左边是一堆控件面板右侧是属性编辑器。先拖一个QLabel标签和一个QPushButton按钮到窗体上。拖完第一件事改对象名。选中控件在右侧属性编辑器的最上面找到objectName标签改成labelHello按钮改成btnSayHello按钮的text属性改成“点我试试”这类文字。对象名这件事一定别偷懒。默认的label_2、pushButton_3这种名字写代码的时候根本分不清谁是谁等到项目稍微大一点那就是给自己埋雷。再把两个控件都选中在窗体空白处右键选栅格布局。不布局的后果是窗口一拉伸控件原地不动非常丑。布局是 Qt 界面开发里最容易被忽略的习惯早点养成。3.3 用信号槽让按钮真正干一件事界面拖好了接下来才是 Qt 的精髓——信号槽。打开mainwindow.cpp在构造函数里补一段#include mainwindow.h #include ui_mainwindow.h MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui-setupUi(this); connect(ui-btnSayHello, QPushButton::clicked, this, [this]() { ui-labelHello-setText(Hello World); }); } MainWindow::~MainWindow() { delete ui; }connect的意思就是当按钮的clicked信号发射时执行后面 lambda 里的代码。你点按钮标签的文字就变成 “Hello World”。这里我刻意用了 Qt5 推荐的函数指针写法而不是老的SIGNAL/SLOT宏。差别在于函数指针写法在编译期就能检查信号和槽是否存在、参数是否匹配老写法跑起来炸了才提示你排查半天对新人非常不友好。快捷键CtrlShiftB生成解决方案再按F5启动调试。弹出一个窗口点一下按钮标签显示 Hello World。到这里你的第一个图形化 C 程序就跑通了。顺便说一嘴Qt 还有一种“自动连接”的写法如果槽函数名刚好叫on_btnSayHello_clicked()setupUi会自动帮你连上不用写 connect。这个技巧项目里很常见但我更建议新手先从手动 connect 学起看代码时逻辑更直白。4. 连点三次“调试”的完整排错链路从报错到能跑4.1 常见编译错误的排查链路头一次跑报错一两回很正常。我把最常见的几类按症状整理了排查顺序症状常见原因最先排查的地方fatal error C1083找不到 QMainWindow.h插件没注册 Qt 版本或包含目录缺失Qt VS Tools - Qt Options - Qt Versions里的路径LNK2019 无法解析的外部符号Qt 库没链接或模块没勾全确认项目是 Qt 模板创建Debug/Release 附加依赖项是否正确报错找不到 ui_mainwindow.huic没跑或项目不是 Qt 工程删除后重新用 Qt 模板新建不要从空项目硬改运行时弹“0xc000007b”32/64 位不匹配检查 VS 平台Win32/x64与 Qt 包位数是否一致如果你真的遇到LNK2019可以这样检查打开项目属性 - 配置属性 - 链接器 - 输入 - 附加依赖项。Qt 插件的正常工程里会自动加Qt5Widgetsd.libDebug 版带 dRelease 版不带。如果你是从普通 C 项目改的这里十有八九是空的。但我不推荐手搓附加依赖项来解决最干净的办法是重新用 Qt 模板建一个项目把代码复制进去。Qt 模板已经把所有自定义生成规则都配置好了手搓很容易顾此失彼。4.2 windeployqt告别“缺少Qt5Widgets.dll”过了编译关还有一关是部署。清完解决方案你到 Debug 目录双击HelloWorld.exe如果本机没装 Qt大概率弹窗说找不到Qt5Widgets.dll。这是正常的因为 Qt 是动态库exe 运行时要到处找依赖。Qt 官方提供了一个工具叫windeployqt专门解决这事。从开始菜单打开Qt 5.11.2 (MSVC 2015 64-bit)这个命令行环境然后进到 exe 所在目录执行windeployqt HelloWorld.exe它会自动把 Qt5Core.dll、Qt5Gui.dll、Qt5Widgets.dll 以及 platforms 目录下的 qwindows.dll 等一堆依赖拷到 exe 旁边。这一步做完把整个目录拷到别的 Windows 机器上就能直接运行。如果你生成的是 Debug 版 exe记得加参数windeployqt HelloWorld.exe --debug不加的话它默认按 Release 处理Debug 程序运行时还是会缺带 d 的Qt5Cored.dll之类。4.3 中文文本乱码的根源与一次性修法最后一个高频坑是中文乱码。现象是标签显示的不是“你好”而是一串生僻字。原因是 VS2015 把源码文件默认存成了 GBK 编码而 Qt5 认为源码是 UTF-8两边各说各话文字就乱了。修法很简单在 VS2015 里打开源文件文件 - 高级保存选项把编码选成Unicode (UTF-8 带签名) - 代码页 65001保存后重新编译。还有土办法是在字符串外面包一层ui-labelHello-setText(QString::fromLocal8Bit(你好));这招在中文 Windows 上能临时救急但换到别的语言环境立马又出问题不建议长期用。我后来几乎所有项目都统一把源文件存成 UTF-8一劳永逸。5. 把Hello World换成你的名字一个能互动的扩展练习5.1 加一个QLineEdit把输入框联动起来跑通 Hello World 之后你可以顺手把它扩展成一个能互动的小程序顺便多练两个控件。回到 Qt Designer再拖一个QLineEdit单行输入框到窗体把objectName改成editName。然后回mainwindow.cpp把构造函数里的 connect 改成connect(ui-btnSayHello, QPushButton::clicked, this, [this]() { QString name ui-editName-text(); if (name.isEmpty()) { ui-labelHello-setText(tr(Hello World)); } else { ui-labelHello-setText(tr(Hello, ) name); } });text()返回输入框里的内容isEmpty()是防空的判断。现在你在输入框里填个名字点按钮标签就会显示 “Hello, 名字”。这一步走完你对“界面控件 代码逻辑 信号槽”三者之间的配合就有感觉了。5.2 一个小习惯让以后的Qt代码更好维护最后分享一个我在多个项目里都坚持的习惯字符串一律用tr()包起来。tr()是 Qt 给多语言和编码管理预留的通道。现在的 Hello World 看不出差别但以后项目要国际化或者团队里有人要改文案tr()包过的字符串能统一提取、统一替换不会散落在代码各处。用它就是在为未来的自己少踩坑。另外一个习惯是lambda 内部只做简单逻辑。如果槽函数里要做的事超过三行就别硬塞在 lambda 里拉出来写成一个普通成员函数再connect到那个函数。代码一大可读性的差距就出来了。这套环境搭好之后其实你以后做很多 Qt 小工具都会沿用同一套流程。我第一次跑通图形化 Hello World 的时候以为还要写不少底层代码结果发现 Qt 把窗口管理、事件分发、消息循环这些都封装好了作为使用者真的只需要关注业务逻辑本身。后面再遇到“窗口卡死”“界面控件找不到”“dll 缺失”这类问题先回头检查版本匹配和插件路径八成都是这些基础环节出了岔子。