
1. 为什么 Qt 6.8 LTS 值得你花时间折腾Qt 6.8 是 Qt 6 系列里第二个长期支持版本上一个 LTS 是 6.2中间隔了差不多三年。这三年里 Qt 6 从“勉强能用”一路打磨到“可以放心上项目”6.8 基本算是 Qt 6 真正成熟的标志性节点。如果你手上还有一堆 Qt 5.15 的老项目在跑或者正纠结新项目到底选 Qt 5 还是 Qt 6那这个版本值得认真看一看。我自己从 Qt 5.12 一路用到 6.8踩过的坑不算少。早期 Qt 6 的坑主要集中在第三方模块缺失、构建系统切换qmake 到 CMake、QML 编译器不稳定这几块。到了 6.8这些问题基本都有了明确的解决方案尤其是 CMake 生态已经非常成熟Qt Creator 对 CMake 项目的支持也顺手了很多。这篇文章会围绕 Qt 6.8 LTS 和 Qt for MCUs 2.9 两个发布来展开重点讲清楚几件事6.8 到底带来了哪些实质性变化、哪些模块值得关注、从 Qt 5 迁移过来要注意什么、Qt for MCUs 2.9 引入 Zephyr RTOS 支持意味着什么、以及在实际项目里怎么落地。内容会偏实操尽量把“为什么这么做”讲透而不是只列一堆新特性清单。适合谁看如果你是用 Qt 做桌面端、嵌入式 HMI、工业上位机的开发者或者正在评估 Qt 6 是否值得升级的技术负责人这篇内容应该能帮你省下不少查文档的时间。如果你刚接触 Qt也可以看但建议先把 Qt 5 或 Qt 6 的基础过一遍再回来读迁移和 MCUs 部分。2. Qt 6.8 LTS 核心变化拆解2.1 LTS 意味着什么和普通版本差在哪先把这个概念说清楚因为很多人对 LTS 有误解。Qt 的版本节奏是每年两个大版本比如 6.7、6.8其中某些版本会被标记为 LTS。LTS 版本的核心区别在于商业支持周期——商业用户可以获得长达 5 年的补丁支持而普通版本通常只有 6 个月左右的维护窗口。但要注意LTS 对开源用户的意义没那么大。开源版本的安全补丁和 bug 修复通常只覆盖到下一个版本发布后的一段时间不会真的给你维护 5 年。所以如果你是开源用户选 LTS 的主要理由是稳定性——LTS 版本在发布前会经过更长时间的测试API 冻结更早不会出现大版本里那种“这个版本改了接口下个版本又改回去”的情况。Qt 6.8 作为 LTSAPI 层面基本冻结后续 6.8.x 系列只会做 bug 修复和安全补丁不会引入破坏性变更。这对企业项目来说很重要——你可以放心地把 6.8.0 作为基线后续小版本升级风险很低。2.2 图形渲染与 RHI 的持续演进Qt 6 最大的架构变化之一就是引入了 RHIRendering Hardware Interface把图形渲染从 OpenGL 抽象出来支持 Vulkan、Metal、Direct3D 11/12 等多种后端。6.8 在 RHI 上继续加码几个值得关注的点Vulkan 后端成熟度提升。早期 Qt 6 的 Vulkan 后端问题不少尤其是多线程渲染场景下容易出现同步问题。6.8 里 Vulkan 后端的稳定性已经可以用于生产环境如果你做的是高性能可视化或者需要精细控制 GPU 的场景可以试试强制指定 Vulkan 后端。Direct3D 12 支持增强。Windows 平台上 D3D12 的性能优势在 6.8 里体现得更明显尤其是配合 QRhi 做自定义渲染管线的时候。不过要注意D3D12 对驱动版本有要求老机器上可能回退到 D3D11。OpenGL 仍然是默认后端。虽然 Qt 在推新后端但 OpenGL 依然是兼容性最好的选择。如果你不追求极致性能保持默认就行别为了用新后端而用新后端。这里有个实操经验切换 RHI 后端可以通过环境变量QSG_RHI_BACKEND来指定比如QSG_RHI_BACKENDvulkan。但不要在生产环境里随便切一定要在目标机器上充分测试。我见过有人本地用 Vulkan 跑得好好的部署到客户机器上因为驱动问题直接黑屏。2.3 Qt Quick 与 QML 的性能改进QML 的性能一直是大家关心的点。6.8 在 QML 引擎上做了几项优化QML 编译器qmlcachegen/qmlsc的编译速度提升。大项目里 QML 文件动辄几百上千个编译时间是个痛点。6.8 优化了编译管线实测下来大型项目的 QML 编译时间能缩短 20% 到 30%。这个提升在 CI 环境里特别明显能省不少构建时间。QML 类型注册的改进。以前用qmlRegisterType注册 C 类型现在更推荐用QML_ELEMENT宏配合 CMake 的qt_add_qml_module。6.8 里这套机制更完善了类型注册的报错信息也更清晰。如果你还在用老式的qmlRegisterType建议趁迁移的时候一起改掉。绑定Binding性能优化。QML 的属性绑定是它的核心特性但绑定过多会导致性能问题。6.8 优化了绑定的求值机制减少了不必要的重算。不过这只是缓解根本的解决办法还是减少绑定层级、避免在绑定里做复杂计算。2.4 网络与串口模块的坑热词里出现了unknown module in qt:serialport和unknown module(s) in qt: serialport说明不少人在用串口模块时遇到了问题。这个错误通常出现在 CMake 项目里原因是Qt6::SerialPort模块没有被正确 find 到。正确的 CMake 写法是这样的find_package(Qt6 REQUIRED COMPONENTS Core SerialPort) target_link_libraries(myapp PRIVATE Qt6::Core Qt6::SerialPort)如果你用的是 qmake对应的是QT serialport出现unknown module的常见原因有几个一是 Qt 安装时没有勾选 SerialPort 模块在线安装器里默认可能不装二是 CMake 的find_package没有包含 SerialPort 组件三是环境变量CMAKE_PREFIX_PATH没指向正确的 Qt 安装路径。排查的时候按这个顺序查基本能定位到问题。网络模块方面6.8 对QNetworkAccessManager做了一些内部优化HTTP/2 的支持更稳定了。如果你做的是需要大量网络请求的应用建议升级后测一下并发场景。2.5 构建系统CMake 已经是唯一正确答案Qt 6 全面转向 CMakeqmake 虽然还能用但官方已经明确表示 qmake 不再是主要构建系统。6.8 里 CMake 的集成更加完善qt_add_executable、qt_add_library、qt_add_qml_module这些命令已经非常成熟。从 qmake 迁移到 CMake 是很多老项目升级 Qt 6 时最大的工作量。我的建议是不要试图在 qmake 里硬撑直接切 CMake。虽然前期要花时间改构建脚本但后续维护成本会低很多。而且 Qt Creator 对 CMake 项目的支持已经很好代码补全、调试、部署都没问题。一个典型的 Qt 6 CMake 项目结构大概是这样cmake_minimum_required(VERSION 3.16) project(MyApp VERSION 1.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Quick) qt_add_executable(MyApp main.cpp mainwindow.cpp mainwindow.h ) target_link_libraries(MyApp PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Quick )注意CMAKE_AUTOMOC、CMAKE_AUTORCC、CMAKE_AUTOUIC这三个开关它们负责自动处理 moc、资源文件和 UI 文件。Qt 6 里这些自动化机制比 Qt 5 更可靠但前提是你要正确设置。3. 从 Qt 5 迁移到 Qt 6.8 的实操路线3.1 迁移前的评估哪些项目该迁哪些不该迁不是所有项目都值得迁移。先做个评估适合迁移的情况新项目、还在活跃开发的项目、需要用到 Qt 6 新特性比如更好的 QML、RHI、新模块的项目、需要长期维护的项目。不适合迁移的情况已经进入维护期、只做 bug 修复的老项目依赖大量 Qt 5 专有模块且这些模块在 Qt 6 里没有替代方案的项目团队没有精力做迁移测试的项目。迁移的成本主要在几个方面构建系统改造qmake 到 CMake、废弃 API 替换、第三方库兼容性、QML 语法调整。小项目可能几天搞定大项目可能要几周甚至几个月。3.2 废弃 API 的替换清单Qt 6 移除或废弃了不少 Qt 5 的 API这里列几个高频的Qt 5 APIQt 6 替代方案说明QString::split的某些重载使用Qt::SplitBehavior枚举名变了QTextStream的setCodecsetEncoding编码处理重构QRegExpQRegularExpressionQRegExp 已移除QDesktopWidgetQScreen多屏处理方式变了QApplication::desktop()QGuiApplication::primaryScreen()同上QLinkedListstd::list或QListQLinkedList 已移除QVectorQListQt 6 里 QVector 就是 QList 的别名QRegExp到QRegularExpression是最常见的迁移点。两者的语法有差异尤其是贪婪匹配和分组引用的写法。迁移时不能简单替换类名要逐个检查正则表达式。3.3 QML 迁移的注意事项QML 方面Qt 6 的变化也不小版本号可以省略了。Qt 6 里import QtQuick 2.15这种写法可以简化为import QtQuick不写版本号默认导入最新版本。建议迁移时统一去掉版本号避免版本混乱。QtQuick.Controls的样式系统变了。Qt 5 里的QtQuick.Controls 1.x和2.x是两套不同的实现Qt 6 只保留了 2.x 的演进版本。如果你还在用 Controls 1迁移工作量会比较大。QtGraphicalEffects被移除。这个模块在 Qt 6 里没有了替代方案是用Qt5Compat.GraphicalEffects兼容模块或者自己用 ShaderEffect 实现。长期来看建议自己实现或者找替代库。QtQuick.Window的调整。窗口相关的 API 有一些变化尤其是Screen相关的属性。3.4 第三方库兼容性排查迁移前一定要排查第三方库。常见的几类Halcon。热词里有qt怎么调用halcon说明做机器视觉的同行不少。Halcon 对 Qt 6 的支持要看版本较新的 Halcon 版本已经支持 Qt 6老版本可能只支持 Qt 5。迁移前先确认 Halcon 版本。FFmpeg。热词里有qt ffmpeg adb学习教程。FFmpeg 本身和 Qt 版本无关但集成方式可能受影响。主要是 CMake 的 find_package 配置要调整。串口/网络库。如果你用的是 Qt 自带的QtSerialPort、QtNetwork迁移相对简单。如果用的是第三方库比如 libmodbus、libserial要确认它们对 Qt 6 的兼容性。报表库。热词里有qt limereport 实现报表打印。LimeReport 对 Qt 6 的支持要看版本老版本可能不兼容。类似的报表库还有 QPrinter、QtRPT 等迁移前都要确认。4. Qt for MCUs 2.9 与 Zephyr RTOS 的落地实践4.1 Qt for MCUs 是什么解决什么问题Qt for MCUs 是 Qt 专门为微控制器MCU做的轻量级图形框架。它和桌面版 Qt 是两套东西——桌面版 Qt 跑在 Linux/Windows 上依赖操作系统Qt for MCUs 可以直接跑在裸机或者 RTOS 上资源占用极小适合那些内存只有几百 KB、主频几十 MHz 的 MCU。它的核心价值在于让嵌入式 HMI 开发也能用 QML。传统 MCU 上做界面要么用段码屏要么用简单的图形库比如 emWin、LVGL开发效率低、效果差。Qt for MCUs 让你用 QML 描述界面然后编译成适合 MCU 的二进制兼顾开发效率和运行性能。热词里有linux跑qt还是lvgl这其实是个常见的选择题。简单说如果你的硬件跑得动 Linux比如 Cortex-A 系列用桌面版 Qt如果是 Cortex-M 系列 MCU资源紧张用 Qt for MCUs 或者 LVGL。LVGL 更轻量但生态和工具链不如 Qt 完善Qt for MCUs 开发体验更好但资源占用略高。4.2 Zephyr RTOS 支持意味着什么Qt for MCUs 2.9 最大的变化是增加了对 Zephyr RTOS 的支持。Zephyr 是一个开源的实时操作系统在嵌入式领域越来越流行尤其是 Nordic、NXP、Espressif 等厂商的芯片上。之前 Qt for MCUs 主要支持 FreeRTOS 和裸机现在加上 Zephyr意味着你可以在 Zephyr 项目里直接集成 Qt for MCUs 做界面利用 Zephyr 的设备驱动、网络协议栈、电源管理用 Zephyr 的构建系统west CMake管理整个项目这对已经在用 Zephyr 的团队来说是好事——不用为了做界面而换 RTOS。对还没选 RTOS 的团队来说Zephyr Qt for MCUs 也是一个值得考虑的方案。4.3 在 Zephyr 上跑 Qt for MCUs 的实操步骤这里给一个基于常见实践的集成流程。具体细节可能因芯片和开发板而异但整体思路是通用的。第一步准备 Zephyr 开发环境。用 west 工具初始化 Zephyr 工作区west init ~/zephyrproject cd ~/zephyrproject west update然后安装 Zephyr SDK 和 Python 依赖。这一步按 Zephyr 官方文档走就行。第二步获取 Qt for MCUs。Qt for MCUs 是商业授权产品需要从 Qt 官网下载。下载后解压到某个目录比如~/QtForMCUs。第三步配置 Qt for MCUs 的 Zephyr 后端。Qt for MCUs 提供了一个 Zephyr 的 board 定义和驱动适配层。你需要把 Qt for MCUs 的 Zephyr 模块路径加到ZEPHYR_EXTRA_MODULES环境变量里export ZEPHYR_EXTRA_MODULES~/QtForMCUs/zephyr第四步创建应用项目。用 Qt for MCUs 提供的模板创建项目然后在CMakeLists.txt里指定 Zephyr 作为目标平台。Qt for MCUs 的构建系统会调用 Zephyr 的构建流程最终生成可烧录的固件。第五步编译和烧录。用 west build 编译然后用 west flash 烧录到开发板。Qt for MCUs 的 QML 代码会被编译成 C 代码再和 Zephyr 一起编译成固件。这里有个关键点Qt for MCUs 的 QML 是编译期处理的不是运行期解释的。这意味着 QML 里的动态特性比如动态创建对象、复杂的绑定支持有限。写 QML 的时候要按 Qt for MCUs 的规范来不能照搬桌面版 QML 的写法。4.4 资源受限环境下的优化技巧MCU 上资源紧张优化是必须的。几个实操经验图片资源用 RLE 或自定义压缩。Qt for MCUs 支持图片压缩但压缩率高的格式解码慢。要在压缩率和解码速度之间找平衡。实测下来简单的 RLE 压缩对图标类图片效果不错。减少图层数量。MCU 的 GPU如果有的话性能有限图层多了会卡。尽量把静态内容合并到一个图层只把需要频繁更新的部分单独分层。动画用硬件加速。如果 MCU 支持 DMA2D 或者类似的 2D 加速器一定要用上。Qt for MCUs 有对应的后端适配配置对了能大幅提升动画流畅度。字体裁剪。中文字体动辄几 MBMCU 上放不下。要用字体裁剪工具只保留用到的字符。Qt for MCUs 提供了字体转换工具可以把 TTF 转成适合 MCU 的格式。内存池预分配。MCU 上不要用动态内存分配容易碎片化。Qt for MCUs 支持静态内存池配置把 UI 对象需要的内存提前分配好。5. 常见问题与排查技巧实录5.1 Qt 6.8 安装与模块缺失问题问题CMake 报unknown module(s) in qt: serialport这个前面提过核心原因是模块没装或者没 find 到。排查步骤检查 Qt 安装目录下有没有Qt6SerialPort相关的库文件。如果没有用 Qt 维护工具MaintenanceTool补装 SerialPort 模块。检查 CMakeLists.txt 里find_package是否包含了 SerialPort 组件。检查CMAKE_PREFIX_PATH是否指向正确的 Qt 安装路径。如果用的是 IDE比如 Qt Creator检查 Kit 配置里的 Qt 版本是否正确。问题cannot mix incompatible Qt library (5.15.3) with this library (5.15.2)这是典型的版本混用问题。系统里装了多个 Qt 版本运行时链接到了错误的库。解决办法检查LD_LIBRARY_PATHLinux或PATHWindows里是否有多个 Qt 路径。用lddLinux或dumpbin /dependentsWindows查看可执行文件实际链接的 Qt 库。清理环境变量确保只保留目标 Qt 版本的路径。如果是打包发布用windeployqtWindows或linuxdeployqtLinux自动收集依赖。5.2 绘图与性能相关问题问题QChart 曲线刷新卡顿能不能放到另一个线程可以但要注意 QChart 不是线程安全的。正确的做法是在后台线程计算数据然后通过信号槽把数据传到主线程在主线程更新图表。不要直接在后台线程操作 QChart 对象。如果数据量很大考虑用QChart::setAnimationOptions(NoAnimation)关掉动画或者用QLineSeries::replace批量替换数据点而不是逐个 append。问题Qt 绘图效率比较QPainter 和 QML 哪个快看场景。QPainter 适合复杂的自定义绘制尤其是需要精细控制每个像素的场景。QML 适合声明式的 UI配合场景图Scene Graph可以利用 GPU 加速。如果是大量简单图形QML 通常更快如果是复杂路径绘制QPainter 可能更合适。实测下来QML 的场景图在 GPU 加速下几千个简单图元的渲染可以轻松跑到 60fps。QPainter 在 CPU 上绘制同样数量的图元可能只有 20-30fps。但 QPainter 配合 OpenGL 后端也能加速只是配置麻烦一些。5.3 开发环境配置问题问题VS Code Qt 5.9 怎么配置Qt 5.9 比较老了建议至少升到 Qt 5.15。如果必须用 5.9配置步骤安装 Qt 5.9 和对应的编译器MinGW 或 MSVC。VS Code 安装 C/C 扩展和 Qt 相关扩展比如 Qt Tools。配置c_cpp_properties.json把 Qt 的 include 路径加进去。配置tasks.json用 qmake make 或者 CMake 构建。配置launch.json设置调试器路径和环境变量。说实话VS Code 配 Qt 不如直接用 Qt Creator 省事。Qt Creator 对 Qt 项目的支持是原生的代码补全、调试、UI 设计、部署都集成好了。除非你有特殊理由必须用 VS Code否则建议用 Qt Creator。问题Qt Creator 代码对齐快捷键不好用Qt Creator 默认的代码格式化快捷键是CtrlI对齐选中行。如果不好用检查是不是和输入法快捷键冲突了。是不是在设置里改了快捷键映射。可以自定义格式化规则工具 - 选项 - C - 代码风格配置好之后用CtrlShiftI格式化整个文件。5.4 打包与发布问题问题Qt 发布软件怎么打包依赖Windows 上用windeployqtwindeployqt --release --no-translations myapp.exeLinux 上用linuxdeployqt或者手动收集依赖。macOS 上用macdeployqt。注意几点一是要包含 Qt 的插件platforms、imageformats、styles 等windeployqt默认会带上二是如果用了 OpenSSL要手动把 libssl 和 libcrypto 拷进去三是如果用了第三方库要确认它们的依赖也被打包了。问题Qt 国内镜像下载慢Qt 官方下载服务器在国内访问确实慢。可以用国内镜像比如清华、中科大、阿里云的镜像。在线安装器可以在设置里配置镜像源。离线安装包也可以从镜像站下载。不过要注意镜像站可能不是实时同步的新版本发布后可能要等几天才有。如果急着用新版本还是得从官方源下。5.5 常见问题速查表问题现象可能原因解决方法unknown module in qt:serialport模块未安装或未 find补装模块检查 CMake find_packagecannot mix incompatible Qt library多版本 Qt 混用清理环境变量统一 Qt 版本QML 编译报错QML 语法不兼容 Qt 6检查 import 语句去掉版本号程序启动黑屏RHI 后端不兼容切回 OpenGL 后端串口打不开权限问题Linux把用户加到 dialout 组打包后缺少 DLL依赖未收集用 windeployqt 自动收集QChart 刷新卡顿主线程阻塞数据计算放后台线程主线程更新 UI中文显示乱码编码设置问题统一用 UTF-8设置 QTextStream 编码6. 升级决策与长期维护建议6.1 现在升级还是再等等Qt 6.8 是 LTSAPI 稳定bug 修复有保障。如果你还在 Qt 5.15现在是个不错的升级时机。但升级前要评估项目依赖的第三方库是否支持 Qt 6。团队是否有时间做迁移和测试。是否有必须用 Qt 6 新特性的需求。如果项目稳定、没有新需求、团队精力有限可以再等等。但要注意 Qt 5.15 的开源支持已经结束后续安全漏洞不会修复长期来看还是要升。6.2 版本锁定与升级策略生产项目建议锁定具体版本比如6.8.0不要用6.8.x这种浮动版本。升级时先在开发环境验证再上测试环境最后上生产。每次升级都要跑完整的回归测试尤其是 UI 和图形相关的部分。如果用的是商业版可以订阅 Qt 的 LTS 支持获得官方补丁和技术支持。开源版的话关注 Qt 的 bug tracker及时应用社区补丁。6.3 嵌入式项目的选型建议嵌入式 HMI 选型我的经验是Cortex-A Linux用桌面版 Qt 6.8功能最全开发效率最高。Cortex-M RTOS用 Qt for MCUs配合 FreeRTOS 或 Zephyr。资源极度受限考虑 LVGL 或 emWinQt for MCUs 虽然轻量但也有最低资源要求。需要功能安全认证Qt for MCUs 有安全认证版本但成本较高要提前评估。Zephyr Qt for MCUs 的组合适合那些已经在用 Zephyr 或者计划用 Zephyr 的团队。Zephyr 的生态在快速成长长期来看是个不错的选择。但要注意 Zephyr 的学习曲线尤其是设备树Device Tree和 Kconfig 那套东西不熟悉的话前期会比较痛苦。6.4 我个人的一些实操体会用了这么多年 Qt有几个体会比较深不要追新版本。新版本发布后至少等一两个小版本再上生产让社区先踩坑。6.8.0 刚发布时可能有些边角问题6.8.1 或 6.8.2 会更稳。构建系统早切早好。qmake 到 CMake 的迁移越早做越好拖得越久包袱越重。新项目直接用 CMake别犹豫。QML 和 C 的边界要清晰。QML 负责 UIC 负责逻辑不要混着写。QML 里做复杂计算是性能杀手C 里做 UI 布局是自找麻烦。测试要覆盖图形部分。Qt 的图形渲染在不同平台、不同驱动上表现可能不一样。自动化测试要包含截图对比确保 UI 没有意外变化。文档和社区是最好的老师。Qt 的官方文档质量很高遇到问题先查文档。社区方面Qt 的论坛和 Stack Overflow 上的 Qt 标签都很活跃大部分问题都能找到答案。最后分享一个小技巧如果你在迁移过程中遇到某个 API 不知道对应 Qt 6 的哪个替代可以用 Qt 的QT_DISABLE_DEPRECATED_BEFORE宏来定位。把这个宏设成0x050F00Qt 5.15编译时会报出所有用到的废弃 API然后逐个替换。这个方法比手动查文档快得多。