部署 QML 应用程序
QML 文档由 QML Runtime 加载和运行。这包括 Declarative UI 引擎以及内置 QML 类型和插件模块。QML Runtime 还可访问第三方 QML 类型和模块。
使用 QML 的应用程序必须调用 QML Runtime 才能运行 QML 文档。你可以通过创建QQuickView 或QQmlEngine 来做到这一点,如下所述。此外,Declarative UI 软件包还包括qml
工具,可加载.qml
文件。该工具可用于开发和测试 QML 代码,而无需编写 C++ 应用程序来加载 QML Runtime。
使用Qt Creator
Qt Creator将 QML 应用程序部署和打包到各种平台。对于移动设备,Qt Creator 可直接将应用程序捆绑到相应的平台包格式,如 APK。
在目标平台上运行应用程序时,应用程序需要访问 QML 库的位置。如果使用qmake,QT_INSTALL_QML
环境变量会指向库的位置。Qt 安装程序会将 QML 库安装在:<version>
/
<compiler>/qml
目录中。
QML 缓存
QML Runtime 通过解析 QML 文档并生成字节码来加载 QML 文档。大多数情况下,文档自上次加载后就没有改变过。为了加快加载过程,QML Runtime 会为每个 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
指令启用 Ahead-of-Time 编译。
使用 QML 场景制作原型
Declarative UI 软件包包含一个QML Runtime 工具qml,可加载和显示 QML 文档。这在应用程序开发阶段非常有用,可用于制作基于 QML 的应用程序原型,而无需编写自己的 C++ 应用程序来调用 QML Runtime。
在应用程序中初始化QML Runtime
要运行使用 QML 的应用程序,您的应用程序必须调用 QML Runtime。这需要编写 Qt XML C++ 应用程序,通过以下任一方式加载QQmlEngine :
- 通过QQuickView 实例加载 QML 文件。
- 创建QQmlEngine 实例并通过QQmlComponent 加载 QML 文件。
使用 QQuickView 初始化
QQuickView 是一个基于 的类,可以加载 QML 文件。例如,如果有一个 QML 文件, ,它将看起来像这样:QWindow application.qml
import QtQuick Rectangle { width: 100; height: 100; color: "red" }
它可以像这样加载到 Qt XML 应用程序的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
的内容。
构建文件
qmake使用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 中的任何图形项目,您可以在上面的代码中用QCoreApplication 替换QGuiApplication 。这样,您就可以将 QML 作为一种语言来使用,而无需依赖于 Qt GUI模块。
用 QML 使用 Qt 资源系统
Qt 资源系统允许将资源文件作为二进制文件存储在应用程序可执行文件中。Qt 资源系统用于 QML 应用程序,因为它能让 QML 文件和其他资源(如图像和声音文件)通过资源系统 URI 方案而不是文件系统资源的相对路径或绝对路径来引用。
注意: 使用资源系统意味着,每当 QML 源文件发生变化时,应用程序可执行文件通常必须重新编译,以更新软件包中的资源。
CMake QML 模块 API会自动将 QML 文件放入资源系统。要访问它们,可将 QML 主文件作为资源加载,或以qrc
方案作为 URL 加载。在资源系统中放置 QML 文件的路径可以通过连接下列文件找到:
- 您传给qt_add_qml_module 的
RESOURCE_PREFIX
。 /qt/qml
, 如果您没有将RESOURCE_PREFIX
传递给qt_add_qml_module,且QTP0001策略设置为NEW
./
, 如果您没有通过RESOURCE_PREFIX
到qt_add_qml_module,并且QTP0001策略为not
设置为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++ 代码才能使用该方案引用资源文件。
相关信息
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.