QtJuniorCoding

Что такое Qt Resource System (файлы qrc) и как её использовать?

Qt Resource System (.qrc) встраивает файлы прямо в бинарник. Доступ происходит через схему qrc:/ или :/ в C++ и QML. В CMake ресурсы подключаются через qt_add_resources() или qt_add_qml_module().

Qt Resource System — файлы .qrc

Qt Resource System позволяет встраивать файлы (изображения, QML, шрифты, JSON, звуки и т.д.) прямо в бинарный исполняемый файл или библиотеку. Это избавляет от зависимости от структуры файловой системы на машине пользователя и упрощает дистрибуцию приложения. Доступ к ресурсам осуществляется через URL-схему qrc:/.

Структура .qrc файла

<!-- resources.qrc -->
<!DOCTYPE RCC>
<RCC version="1.0">
  <qresource prefix="/">
    <file>images/logo.png</file>
    <file alias="main.qml">qml/main.qml</file>
  </qresource>
  <qresource prefix="/fonts">
    <file>fonts/Roboto-Regular.ttf</file>
  </qresource>
</RCC>

Атрибут alias задаёт имя, по которому файл будет доступен в коде — независимо от фактического пути на диске.

Подключение ресурсов в CMake (Qt 6)

qt_add_resources(app "app_resources"
    PREFIX "/"
    FILES
        images/logo.png
        qml/main.qml
        fonts/Roboto-Regular.ttf
)

Или с помощью отдельного .qrc-файла:

qt_add_resources(app resources.qrc)

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

RESOURCES += resources.qrc

Доступ к ресурсам в C++

#include <QFile>
#include <QImage>
#include <QFontDatabase>
#include <QDebug>

void resourceDemo()
{
    // Чтение текстового файла
    QFile f(":/config/settings.json");  // qrc:/ или :/ — одно и то же
    if (f.open(QIODevice::ReadOnly)) {
        QByteArray data = f.readAll();
        qDebug() << data;
    }

    // Загрузка изображения
    QImage img(":/images/logo.png");
    qDebug() << img.size();

    // Регистрация шрифта
    int id = QFontDatabase::addApplicationFont(":/fonts/Roboto-Regular.ttf");
    QString family = QFontDatabase::applicationFontFamilies(id).at(0);
    QFont font(family, 14);
}

Доступ из QML

import QtQuick 2.15

Image {
    source: "qrc:/images/logo.png"  // или просто ":/images/logo.png"
}

Text {
    font.family: "Roboto"  // шрифт зарегистрирован через C++
    text: "Hello"
}

Динамическая загрузка ресурсов

Ресурсы можно загружать из внешних .rcc-файлов во время выполнения через QResource::registerResource(). Это позволяет реализовать плагинную архитектуру или обновляемые ресурсы без перекомпиляции:

// Сгенерировать: rcc --binary resources.qrc -o resources.rcc
if (!QResource::registerResource("/path/to/resources.rcc")) {
    qWarning() << "Failed to load external resources";
}
// После регистрации: :/ пути работают как обычно
QFile f(":/images/logo.png");

Подводные камни

  • Чувствительность к регистру: в .qrc путь Images/Logo.PNG и в коде :/images/logo.png — разные ресурсы; регистр в путях учитывается на всех платформах, даже на Windows.
  • Большие файлы: ресурсы компилируются в массивы C++, что раздувает исполняемый файл и увеличивает время компиляции; видео и большие наборы данных лучше поставлять отдельно.
  • Инициализация при статической линковке: при статической линковке сторонних Qt-плагинов ресурсы могут не зарегистрироваться автоматически — нужен явный вызов Q_INIT_RESOURCE(resourcename).
  • qt_add_qml_module vs qt_add_resources: QML-файлы лучше добавлять через qt_add_qml_module, а не вручную через qt_add_resources — иначе не будет AOT-компиляции и правильной регистрации модуля.
  • Псевдонимы (alias): если два файла получают одинаковый alias в одном prefix — компилятор ресурсов не выдаст ошибку, но доступен будет только последний.
  • Относительные пути в QML: Image { source: "logo.png" } ищет файл относительно текущего QML-файла; если оба в ресурсах — работает; если QML в ресурсах, а файл на диске — нет.
  • Обновление ресурсов: встроенные ресурсы нельзя обновить без перекомпиляции приложения; для обновляемых ресурсов используйте внешние .rcc-файлы с registerResource().

Common mistakes

  • Объяснять Qt Resource System qrc только по синтаксису, без жизненного цикла и стоимости.
  • Игнорировать ошибки, null/empty состояния, порядок инициализации или режим сборки.
  • Давать пример, который работает в демо, но ломается при изменении владельца ресурса.
  • Смешивать signals/slots с generic callbacks и забывать про thread affinity.

What the interviewer is testing

  • Кандидат формулирует точную модель для Qt Resource System qrc, а не только определение.
  • Пример компилируем, безопасен по lifetime и соответствует версии технологии.
  • Названы trade-off, ограничения и диагностируемые симптомы ошибки.
  • Понимает границу между C++ кодом, runtime/framework metadata и editor/UI слоем.

Sources

Related topics