概述 —— QML 与 C++ 混合编程
QML 的架构让我们可以通过 C++ 代码轻松地对其进行扩展。Qt QML 模块中的类让 C++ 可以加载和处理 QML 对象,而 QML 引擎与 Qt 元对象系统 集成的特性让 QML 可以调用 C++ 功能。这些能力让我们能够开发将 QML、JavaScript 和 C++ 代码混合在一起的混合应用程序
Qt 给我们提供了以下几种方式实现 QML 和 C++ 的混合开发:
- 像 QML 文档 中那样,用 QML 和 JavaScript 实现前端 UI,用 C++ 实现后台逻辑,实现界面和逻辑代码分离。
- 在 QML 中使用或调用一些 C++ 功能(例如,调用你的应用程序逻辑,使用 C++ 实现的数据模型,或调用第三方 C++ 库中的一些函数)
- 访问 Qt QML 或 Qt Quick C++ API 中的功能(例如,使用 QQuickImageProvider 动态生成图像)
- 用 C++ 实现 QML 对象类型 —— 无论是在你自己的特定应用程序中使用,还是分发给其他人
要向 QML 提供一些 C++ 的数据或功能,必须使用 QObject 派生类。由于 QML 引擎与元对象系统的集成,任何 QObject 派生类的属性、方法和信号都可以在 QML 中访问,如 向 QML 公开 C++ 类型的属性 中所述。一旦此类提供了所需的功能,就可以通过多种方式将其公开给 QML:
- 类可以被 注册为可实例化的 QML 类型,这样它就可以像普通的 QML 对象类型 一样在 QML 代码中被实例化和使用
- 类可以被注册为 单例类型,这样就可以在 QML 代码中导入该类的单个实例,从而可以在 QML 中访问该实例的属性、方法和信号
- 类的实例可以作为 上下文属性 或 上下文对象 嵌入到 QML 代码 中,从而可以在 QML 访问实例的属性、方法和信号
这些是最常见的 QML 代码访问 C++ 功能的方法;关于更多的选项和细节,请看下面章节中提及的文档。此外,除了 QML 访问 C++ 功能之外, Qt QML 模块还提供了反向操作的方法,在 C++ 代码中操纵 QML 对象。有关详细信息,请参阅 在 C++ 中与 QML 对象交互。
最后,C++ 代码可以集成到 C++ 应用程序或 C++ 插件中,具体取决于它是作为独立应用程序发布还是作为库发布。插件可以与 QML 模块集成,然后可以在其他应用程序中导入和使用 QML 代码;有关更多信息,请参阅 在 C++ 插件中提供类型和功能。
选择正确的方式集成 C++ 和 QML
要快速确定哪种集成方法适合你的情况,可以使用以下流程图:
有关流程图中宏的描述,请参阅 在 C++ 中定义 QML 类型 文档。
向 QML 公开 C++ 类型的属性
由于 QML 引擎与 Qt 元对象系统的集成,QML 可以很容易地用 C++ 扩展。这种集成可以让 QML 访问任何 QObject 派生类的属性、方法和信号:可以读取和修改属性,可以在 JavaScript 表达式里调用方法,并根据需要为信号自动创建信号处理程序。此外,可以在 QML 访问 QObject 派生类的枚举值。
有关详细信息,请参阅 向 QML 公开 C++ 类型的属性。
在 C++ 中定义 QML 类型
QML 类型可以在 C++ 中定义,然后在 QML类型系统 中注册。这可以将 C++ 类实例化为 QML 对象类型,从而使自定义对象类型可以用 C++ 实现,并集成到现有的 QML 代码中。C++ 类也可以出于其他目的进行注册:例如,它可以注册为 单例类型,来让 QML 代码导入单个类实例,也可以注册为可以在 QML 访问的不可实例化类的枚举值。
此外,Qt QML 模块提供了定义 QML 类型的机制,这些类型与附加属性和默认属性等 QML 概念集成。
有关 C++ 注册和创建自定义 QML 类型的更多信息,请参阅 在 C++ 中定义 QML 类型 文档。
使用上下文属性将 C++ 对象嵌入 QML 中
C++ 对象和值可以使用 上下文属性 和 上下文对象 直接嵌入到已加载 QML 对象的上下文(或 范围)中。这是通过 Qt QML 模块提供的 QQmlContext 类实现的,该类将数据公开到 QML 组件的上下文中,可以将数据从 C++ 注入 QML。
有关更多信息,请参阅 使用上下文属性将 C++ 对象嵌入 QML 中。
在 C++ 中与 QML 对象交互
QML 对象类型可以在 C++ 实例化并检查,以便访问它们的属性、调用它们的方法和接收它们的信号通知。这是因为所有 QML 对象类型都是使用 QObject 派生类实现的,QML 引擎能够通过 Qt 元对象系统动态加载和内省对象。
警告:虽然可以在 C++ 访问 QML 对象并对其进行操作,但除了用于测试和原型设计之外,不建议使用这种方法。QML 与 C++ 混合编程的优势之一是能够在 QML 中独立于 C++ 逻辑和数据集后端实现 UI,如果 C++ 端直接操作 QML,优势就没了,还让我们在不影响其 C++ 对应项的情况下更改 QML UI 变得困难。
有关在 C++ 访问 QML 对象的更多信息,请参阅 在 C++ 中与 QML 对象交互 文档。
QML 和 C++ 之间的数据类型转换
当在 QML 和 C++ 之间交换数据值时,QML 引擎会将它们转换为适合在 QML 或 C++ 使用的正确数据类型,前提是引擎知道所涉及的数据类型。
有关引擎支持的内置类型以及在 QML 和 C++ 之间交换时如何转换这些类型以供使用的信息,请参见 QML 和 C++ 之间的数据类型转换。