预编译说明
将编译后的 QML 文档自动缓存到缓存文件中可大大加快应用程序加载时间。但是,创建缓存文件和初始化初始仍然需要一些时间,尤其是在应用程序第一次启动时。为了避免这个初始步骤并从一开始就提供更快的启动时间,Qt 的构建系统允许您在编译C++ 部分的应用程序时提前执行 QML 文件。
提前编译的一个好处是,如果QML文档中出现语法错误,则在应用程序编译时提醒而不是在加载文件运行时收到通知。
如果您使用的是 CMake QML 模块 API,这将自动发生,而对于 qmake,请参阅下面的部分。
qmake 在使用qmake时,为了使用提前编译好的QML文件部署应用程序,必须以特定的方式组织文件和构建系统:
- QML 所有文档(包括
JavaScript
文件)都必须通过 Qt 的资源系统,作为资源包含在系统内。- 您的应用程序必须通过
qrc:/// URL
方案加载 QML 文档。- 您可以使用
CONFIG+=qtquickcompiler
指令启用提前编译。
基于QML场景的原型设计
声明式UI(Declarative UI
)包包括一个QML运行时工具QML,它加载并显示QML文档。这在应用程序开发阶段非常有用,可用于对基于 QML 的应用程序进行原型设计,而无需编写您自己的 C++ 应用程序来调用 QML 运行时。
QML程序运行时初始化
要运行和使用 QML 的应用程序,您的应用程序必须调用 QML 运行时环境。这是通过编写一个Qt C++ 应用程序来完成的,该应用程序通过以下任一方式加载 QQml
引擎:
:::success
- 通过
QQuick View
实例加载QML文件。 - 创建
[QQmlEngine](https://doc.qt.io/qt-6/qqmlengine.html)
实例并使用[QQmlComponent](https://doc.qt.io/qt-6/qqmlcomponent.html)
加载 QML 文件。 :::QQuick View初始化
QQuick View
是一个基于QWindow
的类,可以加载QML文件。例如,如果有一个QML文件application.qml
,它看起来像这样: ```ruby import QtQuick
Rectangle { width: 100; height: 100; color: “red” }
它可以像这样在` main.cpp` 文件中进行加载:
```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
的内容。
应用程序的 .pro
项目文件必须为 QT 变量指定声明性模块。例如:
TEMPLATE += app
QT += quick
SOURCES += main.cpp
直接创建QQmlEngine
如果 application.qml
没有任何图形组件,或者出于其他原因希望避免使用 QQuick View
,则可以直接构建 QQml Engine
。在这种情况下,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 资源系统管理资源文件
Qt 资源系统允许将资源文件作为二进制文件存储在应用程序可执行文件中。这在构建混合 QML/C++ 应用程序时非常有用,因为它允许通过资源系统 URI 方案而不是文件系统资源的相对或绝对路径来引用 QML 文件和其他资源(例如图像和声音文件)。 :::warning 注意: 如果您使用资源系统,那么无论何时更改QML源文件,都必须重新编译应用程序可执行文件,以更新包中的资源。 ::: 要在混合 QML/C++ 应用程序中使用资源系统,你需要注意:
- 创建一个
.qrc
资源集合文件,以 XML 格式列出资源文件。- 对于C++来说,使用
:/ prefix
或者使用.qrc
模式作为URL来加载资源文件。
完成此操作后,QML 中由相对路径指定的所有文件都将从资源系统加载,资源系统的使用对QML层是完全透明的,这也意味着所有 QML 代码都应该使用相对路径来引用资源文件,而不应该使用 .qrc
方案。这个方案应该只在 C++ 代码中用于引用资源文件。
这是一个使用Qt资源系统打包的应用程序,其目录结构如下:
project
|- example.qrc
|- main.qml
|- images
|- background.png
|- main.cpp
|- project.pro
main.qml
和 background.png
文件被打包为资源文件。这是在example.qrc
资源集合文件中完成的:
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/">
<file>main.qml</file>
<file>images/background.png</file>
</qresource>
</RCC>
由于 background.png 是一个资源文件,所以main.qml
可以使用example.qrc
中指定的相对路径来引用它。
// main.qml
import QtQuick
Image {
source: "images/background.png"
}
为了让 QML 能够正确定位资源文件,main.cpp
加载main.qml
文件,main.qml
是作为使用 .qrc 方案的资源文件。
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl("qrc:/main.qml"));
view.show();
return app.exec();
}
最后,project.pro
使用 RESOURCES
变量来指示应该使用 example.qrc
来构建应用程序资源:
QT += qml
SOURCES += main.cpp
RESOURCES += example.qrc