90% 的 Qt 教程都在教你用 Qt Creator,但在工业软件团队里,Visual Studio + CMake 才是主流。
为什么不用 Qt Creator?
先说结论:Qt Creator 是个好 IDE,但它不适合所有场景。
如果你的项目满足以下任一条件,Visual Studio 可能是更好的选择:
| 场景 | Qt Creator | Visual Studio |
|---|---|---|
| 团队成员不全是 Qt 开发者 | ❌ 学习成本高 | ✅ 大多数 C++ 开发者已经会用 |
| 需要和其他 C++ 库联调 | 一般 | ✅ MSVC 生态最完整 |
| 需要 MSVC 编译器 | 需额外配置 | ✅ 原生支持 |
| 工业上位机(运动控制卡 SDK 通常只提供 .lib) | 经常踩坑 | ✅ 直接链接 |
| 信创/国产 Linux 适配 | ✅ 跨平台 | ⚠️ 需要 CMake 统一构建 |
关键问题在最后一行:你想同时支持 Windows MSVC 和 Linux GCC,构建系统必须用 CMake。
而一旦用了 CMake,Qt Creator 就只是个编辑器——这个角色 VS 也能做,还做得更好。
环境准备
你需要的工具
| 工具 | 推荐版本 | 下载地址 |
|---|---|---|
| Visual Studio | 2022 / 2025 | visualstudio.microsoft.com |
| Qt | 6.5+(MSVC 版本) | qt.io/download |
| CMake | 3.16+(VS 自带) | 无需额外安装 |
| Git | 任意版本 | git-scm.com |
Visual Studio 安装要点
安装时勾选:
- ✅ 使用 C++ 的桌面开发
- ✅ 其中的 CMake 工具(默认已勾选)
Qt 安装要点
Qt 在线安装器中选择:
- ✅
Qt 6.x.x→MSVC 2022 64-bit(这个是关键!不要选 MinGW) - ✅
Qt 6.x.x→Qt 5 Compatibility Module(如果要兼容 Qt5)
装完后记住 Qt 的安装路径,例如:C:\Qt\6.7.3\msvc2022_64
项目结构
我们的目标是最小化但完整——能编译、能运行、结构可扩展:
qt-cmake-msvc-starter/
├── CMakeLists.txt ← 构建配置
├── CMakeUserPresets.json ← 你的本地 Qt 路径(不进 git)
├── src/
│ ├── main.cpp ← 入口
│ ├── MainWindow.h ← 主窗口声明
│ └── MainWindow.cpp ← 主窗口实现
├── .gitignore
├── LICENSE
└── README.md
CMakeLists.txt 详解
cmake_minimum_required(VERSION 3.16)
project(QtIndustrialStarter VERSION 0.1.0 LANGUAGES CXX)
# C++17 是 Qt6 的最低要求
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 自动处理 moc/uic/rcc — 不需要手动调用 qt_wrap_cpp
set(CMAKE_AUTOMOC ON)
# 查找 Qt — 优先 Qt6,回退 Qt5
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
message(STATUS ">> Qt ${QT_VERSION_MAJOR}.${Qt${QT_VERSION_MAJOR}_VERSION}")
message(STATUS ">> ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
# 可执行文件
add_executable(${PROJECT_NAME}
src/main.cpp
src/MainWindow.cpp
src/MainWindow.h # .h 也要加,AUTOMOC 才能扫描到
)
target_include_directories(${PROJECT_NAME} PRIVATE src)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
# Windows 下不弹控制台窗口
if(WIN32)
set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE TRUE)
endif()
关键点解释
CMAKE_AUTOMOC ON:这是 CMake 的 Qt 集成魔法。它会自动扫描所有包含 Q_OBJECT 的头文件并调用 moc。你不需要像 qmake 那样手动管理 moc 文件。
find_package(QT NAMES Qt6 Qt5):先尝试找 Qt6,找不到就找 Qt5。这样同一个 CMakeLists.txt 可以兼容两个版本。
.h 文件加入 add_executable:很多人忘记这一步,导致 AUTOMOC 扫描不到 Q_OBJECT 宏,编译时报链接错误。这是最常见的坑。
让 CMake 找到 Qt:CMakeUserPresets.json
这是整篇文章最重要的部分。
大多数教程让你改系统环境变量——别这么做。用 CMake Presets:
在项目根目录创建 CMakeUserPresets.json(注意:这个文件 不进 git):
{
"version": 4,
"configurePresets": [
{
"name": "msvc-qt6",
"inherits": "default",
"cacheVariables": {
"CMAKE_PREFIX_PATH": "C:/Qt/6.7.3/msvc2022_64"
}
}
]
}
仓库里的 CMakePresets.json 提供 default preset,你的 CMakeUserPresets.json 继承它并填入本地 Qt 路径。
为什么这样做?
- 每个开发者的 Qt 安装路径不同
CMakeUserPresets.json在.gitignore中,不会污染仓库- Visual Studio 原生支持 CMake Presets,打开项目就能自动识别
用 Visual Studio 打开项目
- 打开 Visual Studio
- 文件 → 打开 → CMake… → 选择
CMakeLists.txt - VS 会自动读取 CMakePresets,配置项目
- 在工具栏选择 preset:
msvc-qt6 - Ctrl+B 编译,F5 运行
就这么简单。不需要装任何 VS 插件,不需要 Qt VS Tools(虽然装了也不坏)。
运行结果
编译成功后你会看到一个暗色主题的工业风窗口:
- 菜单栏(File / View)
- 工具栏(Run / Stop 按钮)
- 中央 Viewport 占位区域
- 底部可折叠的 Log 面板
- 状态栏
这就是工业上位机软件的标准布局骨架。在此基础上,你可以替换中央区域为 VTK 3D 视图、运动控制面板、或者相机画面。
常见问题
Q: 编译报错 LNK2001: unresolved external symbol "public: virtual struct QMetaObject const *...
A:99% 是 AUTOMOC 没扫到你的头文件。确保 .h 文件加入了 add_executable()。
Q: 运行时报 Qt6Widgets.dll not found
A:Qt 的 DLL 没在 PATH 中。两种解决方案:
- 把
C:\Qt\6.7.3\msvc2022_64\bin加入系统 PATH - 或者用
windeployqt打包:windeployqt.exe your_app.exe
Q: 想同时支持 Debug 和 Release?
A:CMake Presets 中加两个配置即可,VS 工具栏可以切换。
Q: 要加 QML / Quick 怎么办?
A:find_package 中加 Quick 组件,target_link_libraries 加 Qt6::Quick。结构不变。
完整模板
以上所有代码已打包成 GitHub 模板仓库,可直接 clone 使用:
git clone https://github.com/timppyy/qt-cmake-msvc-starter.git
cd qt-cmake-msvc-starter
# 创建 CMakeUserPresets.json,填入你的 Qt 路径
# 用 VS 打开 CMakeLists.txt → 编译 → 运行
Star ⭐ 一下支持作者~
下一步
这个模板是起点。后续文章会覆盖:
- 添加 VTK 3D 可视化
- 插件化架构设计
- Design Token 驱动的 QSS 暗色主题系统
- 跨平台适配(Linux GCC + 国产操作系统)
关注我,不迷路 🚀
作者 Felix,工业自动化领域 Qt/C++ 上位机开发,专注 CMake 工具链和跨平台方案。 GitHub: timppyy