Spec-Zone.ru › Qt 5.13

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

Сжатие

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

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

  • best: используйте лучший алгоритм из нижеперечисленных, на максимальном уровне сжатия, чтобы добиться максимального сжатия, используя при этом много времени процессора во время компиляции. Это значение полезно в XML-файле для указания, что файл должен быть максимально сжат, независимо от того, какие алгоритмы rcc поддерживает.
  • zstd: используйте библиотеку https://zstd.net для сжатия содержимого. Допустимые уровни сжатия — от 1 до 19, 1 — наименьшее сжатие (наименьшее время процессора), 19 — максимальное сжатие (максимальное время процессора). Уровень по умолчанию — 14. Специальное значение 0 говорит библиотеке zstd выбрать определённое по умолчанию значение.
  • zlib: используйте библиотеку https://zlib.net для сжатия содержимого. Допустимые уровни сжатия — от 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.13/resources.html

Spec-Zone.ru

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