Spec-Zone.ru › Qt 6.1

Система ресурсов 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.1/resources.html

Spec-Zone.ru

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