部署 QML 应用程序
QML 文档由 QML 运行时加载并运行。这包括声明性 UI 引擎以及内置的 QML 类型插件模块。QML 运行时还提供对第三方 QML 类型模块的访问。
使用 QML 的应用程序必须调用 QML 运行时以运行 QML 文档。您可以通过创建一个 QQuickView 或一个 QQmlEngine 来这样做,如下所述。此外,声明性 UI 包还包含一个 qml
工具,该工具可以加载 .qml
文件。此工具在无需编写用于加载 QML 运行时的 C++ 应用程序的情况下,用于开发和测试 QML 代码非常有用。
使用 Qt Creator 部署应用程序
Qt Creator 将 QML 应用程序部署和打包到各种平台。对于移动设备,Qt Creator 可以直接将应用程序打包成各自平台的包格式,例如 APK。
当您在目标平台上运行应用程序时,您的应用程序需要访问 QML 库的位置。如果您使用 qmake,则 QT_INSTALL_QML
环境变量指向库的位置。Qt 安装程序将 QML 库安装在 <version>
/
<compiler>/qml
目录。
QML 缓存
QML 运行时通过解析 QML 文档并生成字节码来加载 QML 文档。大多数时候,自上次加载以来文档没有变化。为了加快此加载过程,QML 运行时为每个 QML 文档维护一个缓存文件。此缓存文件包含编译的字节码和 QML 文档结构的二进制表示。此外,当多个应用程序使用相同的 QML 文档时,代码所需的内存将在应用程序进程之间共享。在 POSIX 兼容的操作系统上,这些缓存文件是通过 mmap()
系统调用或 Windows 上的 CreateFileMapping()
加载的,从而显著节省内存。
您每次加载更改过的 QML 文档时,缓存都会自动重新创建。缓存文件位于 QStandardPaths::CacheLocation 的子目录中,名称为 "qmlcache"。文件扩展名是 QML 文档的 .qmlc
和导入的 JavaScript 模块的 .jsc
。
即时编译
将编译的 QML 文档自动缓存到缓存文件中,可显著加快应用加载时间。然而,缓存文件的初始创建仍然可能需要时间,尤其是当应用程序首次启动时。为了避免这个初始步骤,并提供从开始就更快启动时间,Qt 的构建系统允许您在进行应用程序 C++ 部分的编译时提前执行 QML 文件的编译步骤。
预编译的一个好处是,如果您的QML文档中存在语法错误,您将在应用程序编译时而非运行时、文件加载时获得通知。
如果您使用的是CMake QML模块API,这将是自动的;对于qmake,请参见下面的部分。
qmake
当使用qmake时,为了以预编译的方式部署应用程序并带QML文件,您必须以一种特定的方式组织文件和构建系统。
- 所有QML文档(包括JavaScript文件)都必须通过Qt资源系统作为资源包含。
- 您的应用程序必须通过
qrc:///
URL方案加载QML文档。 - 您可以使用
CONFIG+=qtquickcompiler
指令启用预编译。
使用QML场景原型
Declarative UI包包括一个QML运行时工具,qml,它可以加载和显示QML文档。在应用程序开发阶段,这是一个在无需编写自己的C++应用程序来调用QML运行时的情况下,基于QML的应用程序原型化的有用功能。
在应用程序中初始化QML运行时
为了运行使用QML的应用程序,您的应用程序必须调用QML运行时。这是通过编写一个Qt C++应用程序来完成的,通过以下方式加载QQmlEngine
:
- 通过一个
QQuickView
实例加载QML文件。 - 创建一个
QQmlEngine
实例,并使用QQmlComponent
加载QML文件。
使用QQuickView进行初始化
QQuickView是一个基于QWindow的类,可以加载QML文件。例如,如果有一个QML文件,名称为application.qml
,那么它将是这样
import QtQuick Rectangle { width: 100; height: 100; color: "red" }
可以像这样在Qt应用程序的main.cpp
文件中加载
#include <QGuiApplication> #include <QQuickView> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQuickView view; view.setSource(QUrl::fromLocalFile("application.qml")); view.show(); return app.exec(); }
这会创建一个基于QWindow
的视图,该视图将显示application.qml
的内容。
构建文件
使用find_package()
命令在Qt6
包中定位所需的模块组件
find_package(Qt6 REQUIRED COMPONENTS Quick)
target_link_libraries(mytarget PRIVATE Qt6::Quick)
有关更多详情,请参阅使用CMake构建概述。
直接创建QQmlEngine
如果application.qml
没有图形组件,或者由于其他原因更愿意避免使用QQuickView,那么可以 直接构建QQmlEngine。在这种情况下,将application.qml
作为一个QQmlComponent
实例加载,而不是放置到视图中
#include <QGuiApplication> #include <QQmlEngine> #include <QQmlContext> #include <QQmlComponent> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlEngine engine; QQmlContext *objectContext = new QQmlContext(engine.rootContext()); QQmlComponent component(&engine, "application.qml"); QObject *object = component.create(objectContext); // ... delete object and objectContext when necessary return app.exec(); }
如果您不使用任何来自Qt Quick的图形元素,可以在上面的代码中将QGuiApplication
替换为QCoreApplication
。这样,您就可以将QML作为一个不依赖于Qt GUI模块的语言使用了。
使用 Qt 资源系统与 QML
Qt 资源系统允许将资源文件以二进制形式存储在应用程序的可执行文件中。Qt 资源系统用于 QML 应用程序,因为它允许使用资源系统 URI 架构来引用 QML 文件和其他资源(例如图像和声音文件),而不是使用相对或绝对路径来引用文件系统资源。
注意: 资源系统的使用意味着应用程序的可执行文件通常必须在更改 QML 源文件时重新编译,以更新包中的资源。
CMake QML 模块 API 自动将您的 QML 文件放置在资源系统中。要访问它们,将您的主 QML 文件作为资源或使用 qrc
方案作为 URL 加载。您可以通过连接 qt_add_qml_module 传递给您的路径来找到资源系统中放置 QML 文件的路径。
- 您已经传递到 qt_add_qml_module 的
RESOURCE_PREFIX
。 /qt/qml
,如果您没有将RESOURCE_PREFIX
传递给 qt_add_qml_module 并且 QTP0001 策略设置为NEW
。/
,如果您没有将RESOURCE_PREFIX
传递给 qt_add_qml_module 并且 QTP0001 策略没有设置为NEW
。- 如果您没有将
NO_RESOURCE_TARGET_PATH
传递给 qt_add_qml_module:使用点代替斜线的您传递给 qt_add_qml_module 的URI
。
例如,一个名为 My.Own.Module
的模块放置在:
:/qt/qml/My/Own/Module/
,如果您指定了/qt/qml
作为RESOURCE_PREFIX
,或者您没有指定RESOURCE_PREFIX
并且 QTP0001 策略设置为NEW
。:/My/Own/Module/
,如果您指定了/
作为RESOURCE_PREFIX
,或者您没有指定RESOURCE_PREFIX
并且 QTP0001 策略没有设置为NEW
。:/Some/Prefix/My/Own/Module/
,如果您指定了Some/Prefix/
作为RESOURCE_PREFIX
:/
,如果您指定了NO_RESOURCE_TARGET_PATH
完成此操作后,所有在 QML 中指定路径的文件都从资源系统中加载。资源系统的使用对 QML 层面完全透明;这意味着所有 QML 代码应使用相对路径来引用资源文件,而不应使用 qrc
方案。这个方案应该仅从 C++ 代码中引用资源文件。
相关信息
- 部署 Qt 应用程序
- 在多个平台上的运行
- 部署到设备
- qtqml-cppintegration-exposecppattributes.html{将 C++ 类型的属性暴露给 QML}
- Qt 资源系统
© 2024 The Qt Company Ltd. 本文档中包含的文档贡献具有各自所有者的版权。提供的文档是在自由软件基金会发布的GNU自由文档许可协议版本1.3的条款下许可的。Qt及其相关标志是芬兰及/或全球其他国家的The Qt Company Ltd.的商标。所有其他商标均为其各自所有者的财产。