Spec-Zone.ru › Qt 5.15

Система ресурсов 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 в качестве атрибутов в теге file файла .qrc.

<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() не требуется, когда ресурс создаётся как часть приложения.

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

Spec-Zone.ru

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