Как сделать файл qrc

Обновлено: 05.07.2024

Если у меня есть несколько ресурсов (изображения, шрифты и т. д.) в разных папках в моем файле qml.qrc, есть ли способ организовать это в Qt Creator?

Например, если в моем файле qml.qrc есть следующее:

Он будет отображаться как длинный список в Qt Creator, например так:

Поскольку этот список может быть очень длинным на протяжении всего проекта, было бы неплохо, если бы они были лучше организованы и разбиты на папки, как в моем каталоге. Есть идеи?

По умолчанию ресурсы доступны в приложении под тем же именем файла, что и в дереве исходников, с префиксом: /или по URL-адресу со схемой qrc.

Также можно указать префикс пути для всех файлов в файле .qrc, используя атрибут префикса тега qresource:

этот пример показывает, как это сделать:

Я только что нашел отличный способ сделать это. Что странно, так это то, что никто больше не предложил это, когда это так тривиально. Возможно, он не работал в старых версиях Qt /Qt Creator, но теперь работает.

Каталог test должен существовать и содержать test.txt

Нет необходимости создавать отдельные теги с разными префиксами. Нет необходимости в атрибутах alias .

Файлы четко организованы в файловой системе и в проводнике проектов и , к ним можно получить доступ из кода с чистыми путями, такими как :/test/test.txt

 screenshot

(на этом снимке экрана показан проект, в котором также есть несколько дополнительных файлов - игнорируйте их)

Бонус 2: вы можете импортировать (добавить) существующий файл /dir (который находится в любом (под) подкаталоге файла qrc), и будет создан правильный синтаксис XML, в результате правильная древовидная структура в проводнике проекта.

То, что я думаю, не очень хорошо работает:

  • Создание файла из Qt Creator из File -> New file or project (или Ctrl-N). Это не позволяет поместить файл в произвольный каталог в файловой системе, только в корневой каталог проекта.
  • Файлы, которые вы поместили в подкаталоги не включено в поиск Qt Creator по всему проекту ( Ctrl+Shift+F ).

Изменить . Я только что заметил, что ОП делает именно то, что я предлагаю. В этом случае он, вероятно, использует более старую версию Qt Creator. Мой 4.1.0.

На самом деле, я бы настоятельно рекомендовал, чтобы не .qml активы вообще были помещены в другой файл ресурсов, потому что большие файлы сократит время сборки приложения . Происходит даже небольшое изменение в источнике qml, которое приведет к перекомпиляции всего файла ресурсов. Если ресурсы находятся в другом файле ресурсов, они не перекомпилируются непрерывно.

Это также позволит эффективно организовать организацию в дополнение к значительному сокращению времени сборки.

Используя псевдоним, вы можете использовать свой файл, аккуратно написав /images/cut-img.jpg вместо /images/images/cut.jpg

Еще один хороший способ просмотра файлов /папок вашего проекта в том виде, в котором они отображаются в вашей файловой системе, - это сделать следующее:

  • Откройте свой проект
  • Нажмите на выпадающее меню над названием вашего проекта, как показано на рисунке ниже:

введите описание изображения здесь

  • Готово, теперь вы можете видеть свои файлы и папки в том виде, в котором они отображаются на вашем FS

Похожие вопросы

Популярные теги

Всем привет. Сразу признаюсь, я начал писать данный пост уже достаточно давно, но времени полностью завершить его написание всё не хватает. Поэтому, сейчас я публикую его в текущем состоянии, а описание трёх незавершённых разделов всё же отложу и постараюсь опубликовать отдельным постом.

Введение

Это заметка, в которой я хотел бы немного описать архитектуру и систему расширений среды разработки Qt Creator. Изначально, я предполагал лишь перевести документ Writing-Qt-Cretor-plugins.pdf, но так уж вышло, что развитие Qt Creator не стоит на месте и во первых, данный документ уже не столь актуален (сам устарел, API поменялось, куски кода не полные и часто не работают), а во вторых со времени его написания появлись дополнительные возможности расширения Qt Creator, которые хотелось бы описать.

Тем не менее, не будь этого документа, не было бы и данной заметки: из него я взял очень много, вплоть до структуры поста, при этом постаравшись где-то что-то выкидывая/заменяя/добавляя сделать пост актуальным для последней на текущий момент времени версии Qt Creator 2.4.0.

Кому может быть полезен данный документ? В первую очередь это конечно же Qt-программисты, которые выбрали данную IDE как основную среду разработки.

Кроме того, благодаря продуманной системе расширений Qt Creator, данный материал будет полезен тем, кто собрался создавать собственные средства разработки, но не хотят начинать писать их с чистого листа: человек может отключить все ненужные ему расширения Qt Creator и написать свои собственные, пользуясь при этом готовыми примерами в исходниках Qt Creator.

Итак, что же нас ожидает под катом (жирным отмечены готовые разделы):

  1. Сборка Qt Creator
  2. Первое расширение
  3. Добавление новых меню и пунктов меню
  4. Архитектура Qt Creator
  5. Добавление нового редактора (Editor)
  6. Добавление боковой навигационной панели
  7. Добавление страницы в диалог настроек
  8. Добавление фильтра в диалог поиска
  9. Добавление нового типа проекта

1. Сборка Qt Creator

Для пользовтелей Windows данный код может отличаться только последней строкой — вместо make нужно будет вызвать mingw32-make или nmake, в зависимости от предпочтений пользователя.

image

Вот и всё. Вы можете запустить Qt Creator из каталога build/bin.

Следует заметить, что это очень важный этап, так как если Вы не соберёте Qt Creator из исходников, Вы не сможете продвинуться дальше и компилировать и тестировать расширения для него.

2. Первое расширение

2.1 Создание проекта расширения Qt Creator
  • DoNothingPlugin.pro
  • DoNothingPlugin.h
  • DoNothingPlugin.cpp
  • DoNothingPlugin.pluginspec
2.2 Служебные файлы

На первый взгляд здесь очень много файлов и каталогов, но на самом деле в этом нет ничего страшного. Разберёмся с увиденным выше и начнём с файла проекта:

Как видим, в данном сгенерированном файле описывается имя (DoNothing) и тип (библиотека) проекта, указывается три файла заголовков и один файл исходного кода, упоминается pluginspec. Указывается размещение исходников Qt Creator, закомментированные инструкции позволяющие устанавливать собранную библиотеку не в каталог Qt Creator, а в локальную директорию пользователя, описан провайдер, от которого зависит итоговое расположение файлов библиотеки. И наконец включаются базовые для всех расширений файлы qtcreatorplugin.pri и coreplugin.pri, которые уже отвечают за правильную линковку нашего расширения со всеми необходимыми библиотеками.

Следующие файлы donothing_global.h:

и donothingconstants.h:

Здесь думаю всё ясно без дополнительных объяснений. А что не понятно — станет понятно, когда этот код будет необходим нам в дальнейшем. Список служебных файлов можно завершить файлом DoNothing.pluginspec.in:

  1. Наименование расширения, которое будет использоваться в названии библиотеки, реализующей его. (В нашем случае DoNothing.dll в Windows и libDoNothing.so в Unix)
  2. Версия расширения
  3. Требуемая расширением версия Qt Creator
  4. Наименование вендора
  5. Copyright
  6. Текст лицензии
  7. Описание
  8. URL вендора
  9. Список расширений от которых зависит данное расширение.
2.3 Реализация расширения

Для успешной компиляции пустого проекта, необходимы два основных файла реализации нашего расширения. Что же они из себя представляют? Главное требование — основной класс расширения должен быть унаследован от базового класса IPlugin и переопределять некоторые его методы.
donothingplugin.h

Рассмотрим файл реализации данного кода более подробно:

Конструктор и деструктор используются лишь для инциализации базовых переменных, не являющихся виджетами и/или действиями (Action).

Функция initialize() вызывается в тот момент, когда Qt Creator решит, что пора инициализировать расширение. Данная функция предназначена для инициализации начального состояния и регистрации всех действий и объектов относящихся к расширению в самом Qt Creator.

Функция будет вызвана только после того, как все расширения от когторых зависит данное расширение уже загружены в память. В коде по умолчанию, как видно из примера выше, уже описано добавление нового пункта меню, но мы остановимся на этом немного позже.

Метод extensionsInitialized() вызывается после окончания инициализации. Служит главным образом помощником тем расширениям, которые зависят от текущего.

Метод aboutToShutdown() вызывается перед тем, как расширение будет выгружено из памяти.

2.4 Сборка и тестирование расширения

Вот таким образом мы можем добавить самое элементарное расширение Qt Creator. Идём дальше.

3 Добавление новых меню и пунктов меню

  • Файл
    -Создать
    -Открыть
    -Недавние файлы
  • Правка
    -Дополнительно
  • Инструменты
  • Окно
    -Панели вывода
  • Справка

Qt-разработчики знают, что меню сами меню реализуются комбинацией классов QMenu и QAction, а их отображением в виде панели занимается класс QMenuBar.

ActionContianer предоставляет меню и панели меню в Qt Creator. Экземпляры данного класса никогда не создаются напрямую, доступ к ним осуществляется через методы ActionManager::createMenu(), ActionManager::createMenuBar() и другие.

Существуют экземпляры ActionContainer, ассоциированные со всеми меню по умолчанию. Для получения экземпляра ActionContainer необходимо использовать подобный код:

3.3 Добавление меню и пунктов меню

Давайте посмотрим, как мы можем добавлять новые пункты меню. Для этого вернёмся к нашей существующей функции initialize() и более подробно глянем на её реализацию.

Код показанный здесь теперь становится намного более понятным. Итак, мы получаем указатель на ActionManager, затем создаём новый пункт меню и назначаем ему сочетание клавиш. После чего создаём собственное меню и в него добавляем созданный только что пункт. Стоит также заметить что вот теперь нам и пригодились константы ACTION_ID и MENU_ID.

image

Далее мы получаем указатель на ActionContainer меню инструментов (M_TOOLS) и добавляем в него наше меню.
Помимо этого, наше сочетание клавиш было внесено в реестр всех сочетаний клавиш приложения и доступно для изменения в его настройках:

Следует также заметить, что свои меню можно добавлять куда угодно. К примеру, если нам было бы необходимо добавить наше меню на главную панель меню, то вместо константы M_TOOLS мы использовали бы константу MENU_BAR. А чтобы спозиционировать наше меню внутри другого меню, следовало бы передать дополнительный параметр функции addMenu()

3.3 Реагирование на события пунктов меню

Так, как пункты меню являются экземплярами класса QAction, то мы можем использовать сигналы посылаемые этими объектами, такими, как triggered(bool) или toggled(bool) и реагировать на них создавая слоты. Пример опять таки можно взять из нашего кода выше:

image

4 Архитектура Qt Creator

Как правило, каждая достаточно большая система имеет свою архитектуру, поняв которую, мы сможем продвигаться дальше куда быстрее. Qt Creator прост и в этой части мы попробуем разобраться в его базовой архитектуре, после чего продолжим разбираться с написанием расширений.

4.1 Ядро Qt Creator

image

4.2 Что такое расширение?
  1. Наследует и реализует интерфейс ExtensionSystem::IPlugin. Далее по тексту будем звать подобный класс “Plugin Class”.
  2. Экспортирует Plugin Class, используя макрос Q_EXPORT_PLUGIN.
  3. Обеспечивает наличие файла (Plugin Name).pluginspec содержащий метаданные о расширении.
  4. Предоставляет один или более объектов, в использовании которых могут быть заинтересованы другие расширения.
  5. Проверяет доступность одного или более объектов предоставляемых другими расширениями.
4.2.1 Как получить спиcок доступных объектов?

Доступные объекты хранятся в пуле объектов внутри PluginManager. Метод allObjects() из PluginManager возвращает весь пул объектов как список указателей на QObject. Ниже показан код, с помощью которого мы могли бы вывести список доступных объектов на печать:

image

Таким образом, после выполнения данного участка кода, мы увидим длинный список доступных нам объектов:

Предоставляемый (экспортируемый) объект — это экземпляр класса QObject (или его потомков) предоставляемый одним расширением и доступный другим расширениям через пул объектов.

4.2.2 Как экспортировать свой объект в список доступных?
  • IPlugin::addAutoReleasedObject(QObject*)
  • IPlugin::addObject(QObject*)
  • PluginManager::addObject(QObject*)
4.2.3 Какие объекты экспортировать?

image

А вот и результат:

4.2.4 Уведомления о вновь экспортируемых объектах.

Когда вызывается метод PluginManager::addObject(), PluginManager посылает сигнал objectAdded(QObject*). Этот сигнал можно использовать для отслеживания того, какие объекты были вновь добавлены во время работы Qt Creator.

Очевидно, что расширение может обрабатывать данный сигнал только после соединения его с каким-либо из своих слотов, а следовательно, он будет получать уведомления только лишь об объектах, добавленных после выполнения его полной инициализации.

Обычно, слот соединённый с данным сигналом следит за одним или несколькими интерфейсами. К примеру, так может выглядеть код, следящий за появлением нового объекта, реализующего интерфейс INavigationWidgetFactory.

4.2.4 Поиск объектов
  • Метод PluginManager::allObjects(), возвращающий список всех доступных объектов.
  • Подключиться к сигналу PluginManager::objectAdded(), который позволяет получить уведомление о вновь добавляемых объектах.
4.3 Аггрегация объектов

При помощи Аггрегации мы можем собирать несколько разрозненных QObject в один объект. Обычно, в Qt Creator этот подход используется для объединения нескольких интерфейсов

Теперь объект bundle содержит в себе указатели на два объекта. Для доступа к интерфейсам мы можем использовать такой код:

Можно включать несколько интерфейсов в один бандл:

А также удалять как добавленные интерфейсы, так и сам бандл:

Сейчас может быть не понятно, зачем вообще здесь нужно упоминание об объектах Aggregation::Aggregate, но в следующих частях он нам ещё пригодится для упрощения реализации и структурирования описываемых примеров.

5 Добавление нового редактора (Editor)

На базовом уровне (тот самый Core Plugin), Qt Creator — это не более чем текстовый редактор. Однако, при наличии соответствующих расширений, его возможности существенно расширяются: в текстовом редакторе появляются подсветка синтаксиса для различных языков, средства рефакторинга и навигации по C++ коду и многое другое. Появляются средства для редактирования UI (Qt Designer), JS/QML, файлов ресурсов QRC, файлов проектов (PRO/PRI), а также шестнадцатеричный редактор для редактирования файлов типа EXE/DLL/SO.

В этой части мы разберёмся, как создавать редакторы для собственных форматов файлов на примере формата HTML. Когда мы закончим с редактором, мы загрузим HTML-файл в редактор и посмотрим что получилось.

5.1 Базовые классы и интерфейсы

Реализации этого интерфейса предоставляют редакторы для различных типов файлов. Объявлен в файле src/plugins/coreplugin/editormanager/ieditor.h

Метод IEditorFactory::mimeType() возвращает mime-тип поддерживаемый редактором. Метод IEditorFactory::createEditor() создаёт конкретный редактор.

5.1.5 Добавление нового mime-типа

Как только мы это сделали — Qt Creator тут же стал ассоциировать все *.html файлы с mime-типом text/html.

5.2 Расширяем Qt Creator редактором HTML.
5.2.1 Реализация HTML Editor Widget

По умолчанию, Qt Creator использует простой текстовый редактор для просмотра HTML-файлов. Мы же делаем двух-табовый редактор, на одном табе которого можно просматривать страничку, а на другом — редактировать её.

  1. Когда пользователь переходит от редактирования исходника к просмотру, содержимое QWeBView должно быть обновлено
  2. Когда пользователь изменяет содержимое, то необходимо выслать сигнал
  3. И наконец нужно следить за изменением заголовка QWebView.

Деструктор лишь удаляет приватный объект:

Метод setContent() задаёт содержимое webView и textEdit. А метод content() соответственно возвращает содержимое. Метод title() возвращает строку которая будет отображаться в списке открытых файлов. Ну и два последних метода обрабатывают связи с сигналами, созданные в конструкторе.

В конструкторе просто выставляем необходимые нам ассоциации. В деструкторе удаляем приватный объект.

Метод setModified() выставляет флаг modified и высылает сигнал changed()

Отсюда возвращаем mime-тип этого класса.

Метод save() вызывается при выборе пункта меню Файл -> Сохранить или по сочетанию клавиш Ctrl+S. Он сохраняет содержимое HtmlEditorWidget (из textEdit) в текущем ассоциированном файле. затем флаг modified выставляется в false.

Метод open() вызывается при выборе пункта Файл -> Открыть. либо Ctrl+O. Загружает файл и передаёт его в фукнцию setContent() нашего виджета редактирования.

Мы реализуем IEditor, чтобы дать Qt Creator возможность использовать наш виджет редактора html и ассоциировать его с HtmlFile.

Объект HtmlEditorData хранит указатели на объекты HtmlEditorWidget и HtmlFile, переменная displayName используется хранения имени редактора, отображаемого пользователю.

Конструктор инициализирует себя, создаёт экземпляр HtmlFile и проставляет ассоциации между всеми тремя объектами. деструктор уже по традиции лишь удаляет приватный объект.

Три простые функции для мапинга.

Метод createNew() обнуляет содержимое HtmlEditorWidget и HtmlFile.

Метод open() передаёт в HtmlFile имя файла для открытия.

Возвращает тип редактора.

displayName используется для отображения имени файла в ComboBox.

Остальные методы не так важны.

Структура HtmlEditorFactoryData содержит private-данные класса HtmlEditorFactory. Конструктор этой структуры инициализирует её с mime-типом содержащемся в HTMLEditor::Constants::C_HTMLEDITOR_MIMETYPE. Также он инициализирует тип редактора значением HTMLEditor::Constants::C_HTMLEDITOR. Все константы объявляются в файле htmleditorconstants.h.

Далее капелька простых привычных методов.

Метод open() передаёт имя файла менеджеру редакторов, который в свою очередь либо создаёт и открывает новый редактор, либо открывает один из уже существующих.

Этот метод возвращает экземпляр класса HtmlEditor.

5.2.5 Основной класс расширения

Мы реализуем класс HtmlEditorPlugin используя те знания, которые мы получили во второй части. Правда немного изменим метод initialize().

6 Добавление боковой навигационной панели

  • Проекты
  • Открытые документы
  • Закладки
  • Файловая система
  • Обзор классов
  • Обзор
  • Иерархия типов
  • и другие.

Помните, мы уже пробовали добавить навигационную панель содержащую табличку в одной из предыдущих частей? Вот сейчас мы будет делать почти тоже самое, но немного усложним задачу.

6.2 Готовим виджет для панели

Вновь создаём проект модуля Qt Creator. И назовём мы его FTPBrowser. Да, именно потому, что в изначальном документе был этот пример. также нам следует заглянуть по этой ссылке, чтобы скачать класс FtpDirModel.

image

Теперь создаём в нашем проекте новый класс формы и приводим форму к такому виду:

Когда пользователь вводит путь к FTP-директории в строку FTP Path и нажимает Go, то содержимое данного FTP тут же загружается в QTreeView находящийся чуть ниже. Я для примера назвал этот виджет FTPBrowserForm. Исходник формы приводить не буду, его можно будет потом забрать вместе со всеми остальными. Переходим сразу к реализации интерфейса.

Метод createWidget() лишь создаёт новый виджет и возвращает указатель на него. Метод displayName() возвращает строчку для показа пользователю.

image

Вот что у нас получилось:

6.3 Сохранение и восстановление состояния панелей

Иногда может понадобиться сохранять/загружать состояние панелей после перезапуска Qt Creator. Для этих целей, в интерфейсе INavigationWidgetFactory существует две специальные виртуальные функции:

Переопределяя эти два метода, мы можем с лёгкостью управлять состоянием наших виджетов. Вот небольшой пример из нашего же кода:

Две простые функции, параметры которых — позиция и указатель на виджет панели.

Фуф… на этом пока всё… оставшаяся часть статьи будет опубликована… когда и если будет дописана =)

Понадобилось мне резко увеличить возможности QtE5 в связи с полученным заказом по изготовлению приложения обработки данных с тепловизора. В связи с этим решил я добавить графических возможностей в QtE5. Ниже то, что получилось добавить.

Ресурсы Qt

Ресурсы — важная составляющая приложения. Отличие ресурсов Qt от общепринятых в Windows в том, что они (ресурсы и механизм их работы) кросплатформенные. Один раз скомпилировав (не важно на какой платформе) файл ресурсов, он будет корректно работать на любой системе, чего нельзя сказать о ресурсах Windows. Ресурсы в Qt могут быть задействованы автоматом, через проект, но на конечном этапе сборки нужен линкёр. Поэтому нам такой способ не подходит, нет у нас под руками С++ с линкёром. Однако, в Qt, оказывается, есть динамический способ загрузки ресурсов. Он напоминает динамическую загрузку DLL. Далее рассматриваем только динамические ресурсы.

Основная идея проста. Прочитать файл ресурсов в память, получив указатель на начало. Однако, в связи с тем, что ресурсы могут быть разные, и, главное, что их может быть много, встает вопрос, как в этом буфере памяти понять, где начинается один ресурс, или заканчивается другой. Однако, Qt всё делает за нас. Имеется универсальный механизм доступа, к ресурсам. Пример: Qpixmap.load(“:icons/exit_icon.ico”). Двоеточие в начале строки говорит о том, что файл грузится из ресурса. Таким образом, как обратится к ресурсу понятно (можно подробнее почитать в документации к Qt), а вот как его (ресурс создать и загрузить) – это проблема.

Создание ресурса. Для этого используем компилятор ресурсов rcc.exe входящий в состав Qt. Структура исходного файла ресурса описана в документации Qt. В качестве примера приведем файл описания ресурса для нашей демо программы.

Это файл: t.qrc

Таким образом, у нас получился файл t.rcc который содержит в сжатом виде наши два файла PNG.

Загрузка ресурса. Есть две почти одинаковых возможности загрузить файл ресурсов. Один способ чисто Qt, второй D + Qt. Разница, как будет видно далее, небольшая.

Способ 1: чистый Qt в QtE5:

Фактически, создаем объект работы с ресурсом и просим его загрузить файл ресурсов. Если на выходе Истина (true), то ресурс загружен. Далее просто обращаемся к ресурсу через двоеточие.

Способ 2: D + Qt в QtE5:

QPixmap и Qbitmap

Следующий пример я срисовал с интернета. Цель: получить строку, на которую вместо цвета натянута фактура (в примере PNG файл).

Все манипуляции делаются в методе Paint, который вызывается на событие PaintWidget. Не буду останавливаться на том, как включить данное событие. Рассмотрим то, что происходит в Paint методе. В демо он называется runPaint(…).

Более подробно можно почитать в инете, где народ на форумах обсуждает данные моменты. Еще одно замечание: не обязательно смотреть С++ примеры. С таким же успехом можно смотреть примеры на python (PyQt5) и т.д.

Посмотрел ради интереса на Lazarus (паскаль). Интересная штука. Попробовал прикрутить к нему (к паскалю) QtE5. Работает!

Посмотрел Go. Там тоже есть работа с Qt (правда 4.7), но проработка значительно сильнее, чем у меня, хотя подход такой же. Методов там раз в 10 больше, чем у меня.

Ну а главное достоинство QtE5 в том, что новые методы и классы вполне можно добавить самому, при этом не нужно ставить кучу дополнительного софта типа Cmake, и т.д и т.п. Достаточно одного QtCreator.

Я хочу добавить фоновое изображение в виджет, и поэтому мне нужен файл ресурсов, но я не могу его создать в Qt Designer. Вот что я сделал:

Из виджета я перехожу в браузер ресурсов и нажимаю кнопку "добавить новый файл", затем появляется новое окно.

Меня просят указать файл.qrc, но этот файл не существует, и я не знаю, как его создать.

Я googled и нашел, что.qrc файлы создаются с помощью Qt Creator.

Не удается создать файл.qrc в Qt Designer? Нужно ли использовать Qt Creator для создания файла.qrc, а затем использовать его в QT Designer?

Я использую Qt Designer с PyQt в CentOS 7.0

Я бы использовал Qt Creator, так как Qt Designer встроен, и вы можете просто создавать файлы ресурсов. Однако, если это не возможно для вас, вот простое содержимое файла данных qrc, которое вы можете использовать: -

Он создает префикс под названием "/images/", готовый добавить изображения к ресурсу. Просто создайте файл с расширением.qrc и добавьте его.

Читайте также: