Using Qt Resources

The Qt Resource System lets you store files in your program's executable. In some ways, this feature resembles a dedicated file system, which we call resource file system. Usually, this file system contains QML code and other assets like images. If you use the QML compiler, the compiled code is always placed in the resource file system. This leads to a few application manager specific considerations, especially when your application needs to support both single-process and multi-process modes.

Compiling Resources

You can add resources as external binary resources or as compiled-in resources; both can be generated from a .qrc file. Typically, external binary resources are stored in a file with the .rcc extension, whereas compiled-in resources are stored in libraries in the Application Manager context.

It's important to understand that each process has its own resource file system. Consequently, to support multi-process mode, resources must be generated separately for the System UI and for each application. Conversely, in single-process mode there is only one resource file system and you must ensure that file paths don't clash. To prevent clashes, we recommend you prefix each application file path with the unique application ID.

Consider the following application file structure:

apps
|---- spaceinvaders
|     |---- main.qml
|     |---- spaceinvaders.qrc
|     ...
|---- grandtheftdolphin
|     |---- main.qml
|     |---- grandtheftdolphin.qrc
|     ...

Without a prefix, in single-process mode, the main.qml files would clash. To avoid this, the .qrc file for spaceinvaders should read like this:

<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="spaceinvaders">
    <file>main.qml</file>
</qresource>
</RCC>

For grandtheftdolphin the prefix should be "grandtheftdolphin", respectively. Generally, all files contained in any .qrc file should be unique; this also includes files that the System UI uses.

The same applies when resources are added directly, without a .qrc file, for instance when defining a QML module, RESOURCE_PREFIX should be set:

qt_add_qml_module(spaceinvaders
    URI "SpaceInvaders"
    RESOURCE_PREFIX spaceinvaders
    QML_FILES main.qml
)

Loading Resources

In addition to the approaches described in The Qt Resource System, the Application Manager provides configuration options to load resources, both – external binary resources and compiled-in resources in the form of a library.

Suppose you have a my.rcc binary file and a myplugin.so library file. These can be loaded into the System UI by adding the following lines to the am-config.yaml file:

ui:
  resources: [ "${CONFIG_DIR}/my.rcc",
               "${CONFIG_DIR}/myplugin" ]

As you can see, the library file extension can be omitted. You can also load these two files into an application by adding the following snippet to the info.yaml file:

runtimeParameters:
  resources: [ "my.rcc",
               "myplugin.so" ]

The resources are loaded when the System UI starts, before the QML engine is instantiated. In multi-process mode the application resources are also loaded into the application process at startup. In single-process mode, resources are loaded when the application first starts and then reused on subsequent invocations; they are never unloaded.

Accessing Resources

The application manager allows for file access in the resource file system, either with the URL scheme (qrc) or the file name prefix (:). Both these options require an absolute file path in the resource file system, such as:

  • qrc:/spaceinvaders/main.qml or qrc:///spaceinvaders/main.qml
  • :/spaceinvaders/main.qml

While the Qt Application Manager accepts this relaxed naming structure, the QML engine distinguishes between URLs and file names. For instance, an Image source property only accepts the qrc scheme.

If you want to specify a relative path, don't use the scheme or file path prefix.

If your files aren't found in the resource file system, you can list the contents of the entire resource file system with the following code snippet:

QDirIterator it(u":"_s, QDirIterator::Subdirectories);
while (it.hasNext()) {
    const QString fn = it.next();
    if (!fn.startsWith(u":/qt-project.org"_s))  // exclude Qt internal files
        qDebug() << fn;
}

© 2024 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.