Spec-Zone.ru › Qt 6.0

Система ресурсов Qt

Система ресурсов Qt — это независимый от платформы механизм хранения двоичных файлов в исполняемом файле приложения. Это полезно, если ваше приложение всегда нуждается в определённом наборе файлов (иконки, файлы локализации и т.д.) и вы не хотите рисковать потерей этих файлов.

Система ресурсов основана на тесном взаимодействии между qmake, rcc (компилятором ресурсов Qt) и QFile.

Файлы коллекции ресурсов (.qrc)

Ресурсы, связанные с приложением, задаются в файле типа .qrc, формате XML, в котором перечислены файлы на диске и, при необходимости, им присвоено имя ресурса, которое приложение должно использовать для доступа к ресурсу.

Вот пример файла .qrc:

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <file>images/copy.png</file>
    <file>images/cut.png</file>
    <file>images/new.png</file>
    <file>images/open.png</file>
    <file>images/paste.png</file>
    <file>images/save.png</file>
</qresource>
</RCC>

Файлы ресурсов, перечисленные в файле .qrc — это файлы, являющиеся частью дерева исходного кода приложения. Указанные пути относительны к каталогу, содержащему файл .qrc. Обратите внимание, что перечисленные файлы ресурсов должны находиться в том же каталоге, что и файл .qrc или в одном из его подкаталогов.

Данные ресурсов могут быть скомпилированы в двоичный файл и, таким образом, доступны непосредственно в коде приложения, или двоичный ресурс может быть создан и позднее зарегистрирован в системе ресурсов кодом приложения.

По умолчанию, ресурсы доступны в приложении под тем же именем файла, что и в дереве исходного кода, с префиксом :/, или с помощью URL с qrc схемой.

Например, путь к файлу :/images/cut.png или URL qrc:///images/cut.png обеспечат доступ к файлу cut.png, расположение которого в дереве исходного кода приложения — images/cut.png. Это можно изменить, используя атрибут alias тега file:

<file alias="cut-img.png">images/cut.png</file>

Затем файл будет доступен как :/cut-img.png в приложении. Также возможно указать префикс пути для всех файлов в файле .qrc с помощью атрибута prefix тега qresource:

<qresource prefix="/myresources">
    <file alias="cut-img.png">images/cut.png</file>
</qresource>

В этом случае файл будет доступен как :/myresources/cut-img.png.

Некоторые ресурсы должны меняться в зависимости от региональных настроек пользователя, такие как файлы локализации или значки. Это делается путем добавления атрибута lang к тегу qresource, задавая строку региональных настроек. Например:

<qresource>
    <file>cut.jpg</file>
</qresource>
<qresource lang="fr">
    <file alias="cut.jpg">cut_fr.jpg</file>
</qresource>

Если региональные настройки пользователя — французский (т.е. QLocale::system().name() возвращает "fr_FR"), :/cut.jpg станет ссылкой на изображение cut_fr.jpg. Для других региональных настроек используется cut.jpg.

См. документацию QLocale для описания формата, который следует использовать для строк региональных настроек.

См. QFileSelector для дополнительного механизма выбора ресурсов, специфичных для региональных настроек, помимо возможностей выбора ресурсов, специфичных для ОС и других функций.

Внешние двоичные ресурсы

Чтобы создать внешний двоичный ресурс, необходимо создать данные ресурса (обычно с расширением .rcc), передав параметр -binary в rcc. После создания двоичного ресурса можно зарегистрировать его с помощью API QResource.

Например, набор данных ресурсов, указанных в файле .qrc можно скомпилировать следующим образом:

rcc -binary myresource.qrc -o myresource.rcc

В приложении этот ресурс будет зарегистрирован кодом примерно такого вида:

QResource::registerResource("/path/to/myresource.rcc");

Скомпилированные ресурсы

Для того, чтобы ресурс был скомпилирован в двоичный файл, файл .qrc должен быть упомянут в файле .pro приложения, чтобы qmake знал о нём. Например:

RESOURCES     = application.qrc

qmake сгенерирует правила make для создания файла под названием qrc_application.cpp, который будет связан с приложением. Этот файл содержит все данные для изображений и других ресурсов в виде статических массивов C++ из сжатых двоичных данных. Файл qrc_application.cpp автоматически пересоздаётся всякий раз, когда изменяется файл .qrc или любой из файлов, на которые он ссылается. Если вы не используете файлы .pro, вы можете либо вручную вызвать rcc, либо добавить правила сборки в вашу систему сборки.

Building resources into an application

В настоящее время Qt всегда хранит данные непосредственно в исполняемом файле, даже в Windows, macOS и iOS, где операционная система предоставляет встроенную поддержку ресурсов. Это может измениться в будущих выпусках Qt.

Ресурсы в приложении Qt для Python

Файл коллекции ресурсов преобразуется в модуль Python с помощью компилятора ресурсов rcc:

rcc -g python application.qrc > application_rc.py

Модуль необходимо импортировать в приложение:

import application_rc.py

Сжатие

rcc пытается сжать содержимое для оптимизации использования дискового пространства в конечных двоичных файлах. По умолчанию, он выполнит эвристическую проверку, чтобы определить, стоит ли сжимать, и сохранит содержимое не сжатым, если сжатие не будет достаточно эффективным. Для управления порогом можно использовать опцию -threshold, которая указывает rcc процент исходного размера файла, который необходимо получить для хранения файла в сжатом виде.

rcc -threshold 25 myresources.qrc

Значение по умолчанию — "70", что означает, что сжатый файл должен быть на 70% меньше исходного (не более 30% исходного размера файла).

Если необходимо, можно отключить сжатие. Это может быть полезно, если ваши ресурсы уже содержат сжатый формат, например, файлы .png, и вы не хотите тратить время процессора при сборке на проверку, можно ли их сжимать. Другая причина — если использование дискового пространства не является проблемой, и приложение предпочитает хранить содержимое как чистые страницы памяти во время выполнения. Для этого используйте параметр командной строки -no-compress.

rcc -no-compress myresources.qrc

rcc также позволяет контролировать уровень сжатия и алгоритм сжатия, например:

rcc -compress 2 -compress-algo zlib myresources.qrc

Также можно использовать threshold, compress, и compress-algo в качестве атрибутов тега .qrc file.

<qresource>
    <file compress="1" compress-algo="zstd">data.txt</file>
</qresource>

Это выберет алгоритм zstd с уровнем сжатия 1.

rcc поддерживает следующие алгоритмы сжатия и уровни сжатия:

  • best: использует лучший алгоритм из перечисленных ниже с максимальным уровнем сжатия для достижения наибольшего сжатия за счёт значительных затрат времени процессора во время компиляции. Это значение полезно в файле XML, чтобы указать, что файл должен быть сжат максимально независимо от того, какие алгоритмы поддерживает rcc.
  • zstd: использует библиотеку Zstandard для сжатия содержимого. Допустимые уровни сжатия варьируются от 1 до 19, 1 — наименьшее сжатие (наименьшее время работы процессора), 19 — наибольшее сжатие (наибольшее время работы процессора). Уровень по умолчанию — 14. Специальное значение 0 заставляет библиотеку zstd выбрать определённое значение по умолчанию.
  • zlib: использует библиотеку zlib для сжатия содержимого. Допустимые уровни сжатия варьируются от 1 до 9, 1 — наименьшее сжатие (наименьшее время работы процессора), 9 — наибольшее сжатие (наибольшее время работы процессора). Специальное значение 0 означает «без сжатия» и не должно использоваться. Значение по умолчанию определено реализацией, но обычно равно 6.
  • none: без сжатия. Это то же самое, что и опция -no-compress.

Поддержка как Zstandard, так и zlib является необязательной. Если библиотека не была обнаружена во время компиляции, попытка передачи -compress-algo для этой библиотеки приведёт к ошибке. Алгоритм сжатия по умолчанию — zstd при включении, zlib — в противном случае.

Использование ресурсов в приложении

В приложении пути к ресурсам могут использоваться во многих местах вместо обычных путей к файлам. В частности, можно передать путь к ресурсу вместо имени файла в конструктор QIcon, QImage или QPixmap:

    cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);

См. пример приложения Application, в котором используется система ресурсов Qt для хранения иконок.

В памяти ресурсы представлены деревом объектов ресурсов. Дерево автоматически создаётся при запуске и используется QFile для разрешения путей к ресурсам. Можно использовать QDir, инициализированный ":/", для навигации по дереву ресурсов с корня.

Ресурсы Qt поддерживают понятие списка путей поиска. Если вы затем ссылаетесь на ресурс с префиксом : вместо :/, ресурс будет находиться с использованием списка путей поиска. Список путей поиска пуст при запуске; вызовите QDir::addSearchPath() для добавления путей в него.

Использование ресурсов в библиотеке

Если у вас есть ресурсы в библиотеке, вам нужно принудительно инициализировать ресурсы, вызвав Q_INIT_RESOURCE() с базовым именем файла .qrc. Например:

MyClass::MyClass() : BaseClass()
{
    Q_INIT_RESOURCE(resources);

    QFile file(":/myfile.dat");
    ...
}

Это гарантирует, что ресурсы будут включены в конечный исполняемый файл приложения в случае статической компоновки. Код инициализации следует размещать рядом с местом использования ресурсов в вашей библиотеке, чтобы клиенты вашей библиотеки связывали ресурсы только в том случае, если они используют функцию библиотеки, которая от них зависит.

Примечание: так как инициализаторы ресурсов, сгенерированные rcc, объявлены в глобальном пространстве имен, вызовы Q_INIT_RESOURCE() также должны выполняться вне любого пространства имён.

Если библиотека включает ресурсы, которые не используются внутри неё, а вместо этого предоставляются клиентам библиотеки, инициализация должна происходить в коде приложения. Например:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Q_INIT_RESOURCE(graphlib);

    QFile file(":/graph.png");
    ...
    return app.exec();
}

Как и прежде, это гарантирует, что ресурсы будут включены в конечный исполняемый файл приложения в случае статической компоновки, а также запустит загрузку библиотеки в случае динамической компоновки, например, плагинов.

Аналогично, если вам необходимо явно разгрузить набор ресурсов (потому что плагин разгружается или ресурсы больше не действительны), вы можете принудительно удалить свои ресурсы, вызвав Q_CLEANUP_RESOURCE() с тем же базовым именем, что и выше.

Примечание: Использование Q_INIT_RESOURCE() и Q_CLEANUP_RESOURCE() не требуется в следующих случаях:

  • При построении ресурса в составе приложения.
  • При построении ресурса с помощью CMake в составе статической библиотеки.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.0/resources.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API