当前位置: 首页 > news >正文

Qt 6 与 Qt 5 存在的兼容性差异

之前有提到。我的是Qt5,我朋友的是Qt 6,由于版本不兼容问题,在迁移时会有问题。所以这一我们说说这两个的区别。(

正文开始喽!

总结来说:Qt5迁移至 Qt 6 需:1. 破坏性变更(必须修改代码)2. 模块和功能的变化3. 构建系统的变化

一、 破坏性变更(需要修改代码)

这些是您在将项目从 Qt 5 迁移到 Qt 6 时最可能遇到并必须修改代码的地方。

1. 对 C++ 标准的要求
  • Qt 5: 最低要求 C++11,但大部分模块仍兼容 C++98。

  • Qt 6强制要求 C++17 标准。这意味着您的编译器和代码都必须支持 C++17。这是 Qt 6 现代化改造的基础。

2. 图形架构的重大改变

这是最核心的差异之一,主要影响与图形渲染相关的代码(尤其是自定义的 QQuickItem 或使用 QPainter 的场景)。

  • Qt 5: 支持多种后端,如 OpenGL、DirectX、Software(软件渲染)。在 Qt Quick 2 中,场景图(Scene Graph)是基于 OpenGL 的。

  • Qt 6: 引入了 RHI(Rendering Hardware Interface) 抽象层。

    • 是什么:RHI 是一个位于 Qt Quick 场景图和具体图形 API(如 Vulkan、Metal、Direct3D、OpenGL)之间的薄抽象层。

    • 为什么:为了实现跨平台图形后端的统一和最佳性能(默认在 macOS 上使用 Metal,在 Windows 上使用 DirectX 12/Vulkan,在 Linux 上使用 Vulkan/OpenGL)。

    • 影响

      • 所有直接使用 OpenGL 调用的代码(例如 QOpenGLFunctionsQOpenGLFramebufferObjectQOpenGLShaderProgram)都需要重写,以使用 QRhi 及其相关类(如 QRhiTextureQRhiRenderBuffer 等)。

      • 自定义的 QQuickItem 或 QQuickFramebufferObject 需要适配新的渲染路径。

    • 兼容方案:Qt 6 提供了 rhi 模块和大量示例来展示如何在新架构下进行渲染。

3. QString 相关变化
  • QString::midQString::leftQString::right:

    • Qt 5: 返回 QString

    • Qt 6: 返回 QStringView。如果您需要 QString,可能需要显式构造或使用其他方法。

  • QStringRef 被移除:由 QStringView 替代。所有使用 QStringRef 的代码都需要替换。

4. QML 注册类型的变化
  • Qt 5: 使用 qmlRegisterType 函数族进行注册。

  • Qt 6强烈推荐使用新的宏 QML_ELEMENT 和 QML_NAMED_ELEMENT(<name>) 在类声明中直接注册。虽然旧的函数仍然存在,但新方式更简洁、更易于维护。

    • Qt 5:// main.cpp
      qmlRegisterType<MyObject>("MyModule", 1, 0, "MyObject");Qt 6:// myobject.h
      #include <QtQml/qqmlregistration.h>
      class MyObject : public QObject {Q_OBJECTQML_ELEMENT // 自动使用类名// 或 QML_NAMED_ELEMENT("MyObject") // 自定义名称...
      };
    • 然后在 CMake 中使用 qt6_add_qml_module 或在 QMake 中正确配置。

5. 容器类迭代器的行为变化
  • Qt 5QMapQHashQSet 等的迭代器行为类似于 std::mapit.key() 和 it.value() 用于访问键值对。

  • Qt 6: 为了与 C++ STL 保持一致,迭代器解引用(*it)现在返回的是 ,而不是一个键值对。

    • 对于 QMap 和 QHash*it 等价于 it.value()

    • 要获取键,仍然需要使用 it.key()

    • 这会影响基于范围的 for 循环:

      
      QMap<int, QString> map;
      // Qt 5 方式 (在Qt 6中错误)
      for (auto &pair : map) {// pair 是 QPair<int, QString> 或类似物int key = pair.key;   // 错误QString value = pair.value; // 错误
      }
      // Qt 5/6 通用正确方式
      for (auto it = map.begin(); it != map.end(); ++it) {int key = it.key();QString value = it.value(); // 或 *it
      }
      // Qt 6 基于范围for循环的正确方式
      for (auto &key : map.keys()) {QString value = map.value(key);
      }
      for (auto &value : map) { // *it 就是value,所以可以直接遍历值// ...
      }

二、 模块和功能的变化

1. 模块的移除和拆分

许多在 Qt 5 中处于“废弃”状态的模块在 Qt 6 中被正式移除。如果需要它们,必须单独安装或寻找替代方案。

  • 被移除的模块

    • QtScript: 已废弃,推荐使用 QJSEngine(在 QtQml 中)。

    • QtXmlPatterns: 已废弃,推荐使用 QXmlStreamReader 或第三方库。

    • QtQuick1 / QtDeclarative: QML 1.0 已被淘汰。

    • QtWebKit: 已被 QtWebEngine 取代(但 QtWebEngine 本身在 Qt 6.4 之前是附加模块,需要单独安装)。

    • QtQuickControls1: 已被 Qt Quick Controls 2 取代。

  • 变为附加模块(需要单独安装):

    • QtWebEngine: 提供浏览器功能。

    • QtSerialPortQtBluetoothQtSensors 等许多不属于核心框架的模块都变成了附加模块。

2. 新的核心模块
  • QtCore5Compat: 这是一个至关重要的兼容性模块。它包含了许多从 Qt 5 核心模块中移除但为了兼容性而保留的类,例如:

    • QRegExp (推荐使用 QRegularExpression)

    • QTextCodec 及其子类

    • QStringRef (已被 QStringView 取代)

    • 旧版本的 QDateTime API

    • 如果您遇到 QRegExp 等类找不到链接的错误,通常需要在 .pro 文件(QT += core5compat)或 CMakeLists.txtfind_package(Qt6 COMPONENTS Core5Compat))中添加这个模块。

3. API 的清理和废弃

许多在 Qt 5 中被标记为“废弃”的旧 API 在 Qt 6 中被彻底移除。编译器会直接报错。

  • 常见例子

    • QColor::light() / QColor::dark() -> 使用 QColor::lighter() / QColor::darker()

    • qVariantFromValue() -> 使用 QVariant::fromValue()

    • QFontMetrics::width() -> 使用 QFontMetrics::horizontalAdvance()


三、 构建系统的变化

1. QMake 到 CMake 的转变
  • Qt 5: 主要支持和推荐使用 QMake (.pro 文件)。

  • Qt 6官方强烈推荐并主要支持使用 CMake。虽然仍然支持 QMake,但所有新的特性和开发都优先面向 CMake。Qt 官方提供的许多工具和集成(如用于 QML 的 qt6_add_qml_module)都是为 CMake 设计的。

2. 新的 QML 模块构建系统
  • 在 Qt 6 中,使用 CMake 管理 QML 模块、资源(qmldirqrc 文件)变得更加简单和强大,通过 qt6_add_qml_module 宏可以一站式处理类型注册、资源打包和模块发现。


迁移建议和总结

  1. 检查编译器:确保您的编译器支持 C++17。

  2. 使用端口工具:运行 qt6_porting_tools 中的 configure 和 cmake 脚本来分析您的代码,它们能识别出许多常见的兼容性问题。

  3. 逐模块处理

    • 首先处理核心模块(QtCore, QtGui, QtWidgets)的编译错误(如废弃的 API)。

    • 然后重点关注图形相关代码(OpenGL -> RHI)。

    • 接着处理 QML 注册和 QML 相关代码。

  4. 添加 Core5Compat 模块:如果遇到 QRegExp 等链接错误,这是最快的解决方案。

  5. 查阅官方文档:Qt 官方提供了非常详细的 Porting from Qt 5 to Qt 6 指南,这是最权威的参考。

http://www.dtcms.com/a/354366.html

相关文章:

  • C# 数组C# 多维数组
  • QML(2) - Qt 中如何注册一个 C++ 类到 QML
  • MySQL的类split方法实现
  • Java表格处理详解以及结合实际项目使用
  • WebStrom-如何设置前端项目快捷启动
  • 29. String, StringBuffer,StringBuilder 的区别是什么
  • 统一虚拟试穿框架OmniTry:突破服装局限,实现多品类可穿戴物品虚拟试穿无蒙版新跨越。
  • 【小白笔记】网速
  • TypeScript:完整的函数类型书写方式
  • 【开题答辩全过程】以超市管理系统为例,包含答辩的问题和答案
  • Linux 系统核心调优:CPU、磁盘 I/O、网络与内核参数实战
  • 流行蝴蝶剑高清重制版Windows10可玩!
  • 小程子找Bug之for循环的初始化表达类型
  • 【美团】放它一马
  • 今日行情明日机会——20250827
  • 即时配送运营平台系统功能分析
  • 寄存器, 堆栈, 汇编指令详解
  • 入门概念|Thymeleaf与Vue
  • 企业微信对接 代理 WXJava Ngnix映射 weixin-java-cp
  • Vue 登录页高低分辨率背景图优化实现
  • mathtype公式存在乱码
  • SqlHelper类的方法详细解读和使用示例
  • Libvio访问异常排查指南
  • sql server 取起始日期到结束日期中自然月最后一天,与日期维度行转列
  • 数据治理:AI健康血液的生命线
  • Elasticsearch数据迁移快照方案初探(一):多节点集群配置踩坑记
  • Anaconda的安装与使用
  • 文本分块的优化策略-语义完整性、控制长度、重叠切分、结合模型,考虑大模型输入限制
  • matlab的app中传递数据
  • 林墨2025全新个人EP《嘻嘻呵呵嘿嘿哈哈》 第三支单曲解锁