Работа с файлами и директориями в Qt

Работа с ресурсами — система ресурсов Qt (Qt Resource System)

обновлено 2 464 просмотров

Введение

Иконки, изображения, файлы переводов, QML-файлы, шрифты и шаблоны — почти любому приложению нужны дополнительные файлы. Если хранить их рядом с exe, их легко потерять или повредить при установке. Система ресурсов Qt (Qt Resource System) решает эту задачу: она встраивает файлы прямо в исполняемый файл приложения независимо от платформы. В статье разберём, как устроен файл .qrc, как обращаться к ресурсам из кода и QML, как подключить ресурсы в qmake и CMake и какие у системы есть ограничения.

Как работает система ресурсов Qt

Ресурсы описываются в файле с расширением .qrc. При сборке компилятор ресурсов rcc превращает перечисленные файлы в исходник C++ со статическими массивами байтов. Этот исходник компилируется и компонуется вместе с приложением. Во время работы программы Qt предоставляет к этим данным доступ через виртуальную файловую систему с путями, начинающимися на :/.

Формат файла .qrc

Файл .qrc — это XML, в котором перечислены файлы с относительными путями:

<!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, или в его подкаталогах. В этом примере все изображения лежат в папке images.

Префиксы и псевдонимы

Атрибут prefix группирует ресурсы под общим виртуальным путём, а атрибут alias задаёт файлу короткое имя:

<RCC>
    <qresource prefix="/icons">
        <file alias="new.png">images/new.png</file>
        <file alias="open.png">images/open.png</file>
    </qresource>

    <qresource prefix="/copy">
        <file>images/copy.png</file>
    </qresource>
</RCC>

Теперь иконка доступна по пути :/icons/new.png, а копирование — по пути :/copy/images/copy.png. Псевдонимы удобны, когда структура папок в проекте может меняться, а пути в коде — нет.

Доступ к ресурсам из кода

По умолчанию ресурс доступен под тем же путём, что и в дереве исходников, с префиксом :/. В QML и других местах, где нужен URL, используется схема qrc::

":/images/copy.png"            // без префикса qresource
":/copy/images/copy.png"       // с префиксом /copy
"qrc:/images/copy.png"         // URL для QML и QUrl

С путями ресурсов работают все классы Qt, которые принимают имя файла:

QIcon icon(":/icons/new.png");
QPixmap logo(":/images/logo.png");

QFile file(":/data/config.json");
if (file.open(QIODevice::ReadOnly)) {
    QByteArray json = file.readAll();
}

В QML ресурсы подключаются так же просто:

Image {
    source: "qrc:/images/logo.png"
}

Подключение ресурсов в qmake

В файл проекта добавьте строку:

RESOURCES += application.qrc

qmake сгенерирует файл qrc_application.cpp со всеми данными в виде статических массивов C++. Он автоматически пересобирается при изменении .qrc или любого из перечисленных в нём файлов.

Подключение ресурсов в CMake

Самый простой способ — включить автоматическую обработку и добавить .qrc в список исходников:

set(CMAKE_AUTORCC ON)

add_executable(myapp
    main.cpp
    application.qrc
)

В Qt 6 есть функция qt_add_resources(), которой можно передать файлы напрямую, без отдельного .qrc:

qt_add_resources(myapp "images"
    PREFIX "/icons"
    FILES
        images/new.png
        images/open.png
)

Ресурсы для разных языков

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

<qresource prefix="/help">
    <file>help.html</file>
</qresource>
<qresource prefix="/help" lang="ru">
    <file alias="help.html">help_ru.html</file>
</qresource>

При русской локали путь :/help/help.html откроет русскую версию, в остальных случаях — английскую.

Внешние ресурсы

Большие наборы файлов (темы оформления, звуки) можно не встраивать в exe, а собрать в отдельный двоичный файл и загружать при запуске:

rcc -binary themes.qrc -o themes.rcc
QResource::registerResource(QCoreApplication::applicationDirPath() + "/themes.rcc");

После регистрации файлы из themes.rcc доступны по обычным путям :/….

Ограничения системы ресурсов

  • Ресурсы доступны только для чтения. Изменить или сохранить файл по пути :/ нельзя.
  • Каждый встроенный файл увеличивает размер исполняемого файла. Видео и большие архивы лучше хранить отдельно.
  • Сторонние библиотеки, которые открывают файлы через стандартный fopen(), не видят пути :/. Такой файл нужно сначала скопировать во временный каталог.
  • При изменении ресурсов приложение нужно пересобрать.

Заключение

Система ресурсов Qt позволяет поставлять приложение одним файлом без риска потерять иконки, QML или переводы. Опишите файлы в .qrc, подключите его через RESOURCES в qmake или CMAKE_AUTORCC в CMake и обращайтесь к ресурсам по путям :/ и qrc:/. Для больших и сменных наборов данных используйте внешние .rcc-файлы.