Spec-Zone.ru › Qt

Создание пользовательских виджетов для Qt Designer

Qt Designer, основанный на архитектуре плагинов, позволяет редактировать пользовательские и сторонние виджеты так же, как стандартные виджеты Qt. Все функции пользовательского виджета доступны в Qt Designer, включая свойства виджета, сигналы и слоты. Так как Qt Designer использует реальные виджеты во время процесса проектирования формы, пользовательские виджеты будут выглядеть так же, как и при предварительном просмотре.

Модуль QtDesigner предоставляет возможность создавать пользовательские виджеты в Qt Designer.

Начало работы

Для интеграции пользовательского виджета с Qt Designer, вам потребуется подходящее описание для виджета и соответствующий .pro файл.

Предоставление описания интерфейса

Чтобы сообщить Qt Designer о типе предоставляемого виджета, создайте подкласс QDesignerCustomWidgetInterface, описывающий различные свойства вашего виджета. Большинство из них предоставляются функциями, которые являются чисто виртуальными в базовом классе, потому что только автор плагина может предоставить эту информацию.

Функция Описание возвращаемого значения
name() Имя класса, который предоставляет виджет.
group() Группа в поле виджетов Qt Designer, к которой принадлежит виджет.
toolTip() Краткое описание для помощи пользователям в идентификации виджета в Qt Designer.
whatsThis() Более подробное описание виджета для пользователей Qt Designer.
includeFile() Заголовочный файл, который должен быть включён в приложения, использующие этот виджет. Эта информация хранится в файлах UI и будет использоваться uic для создания подходящего #includes оператора в коде, который он генерирует для формы, содержащей пользовательский виджет.
icon() Иконка, которая может быть использована для представления виджета в поле виджетов Qt Designer.
isContainer() True, если виджет будет использоваться для размещения дочерних виджетов; false в противном случае.
createWidget() Указатель на QWidget экземпляр пользовательского виджета, созданного с предоставленным родителем.

Примечание: createWidget() — это функция-фабрика, отвечающая только за создание виджета. Свойства пользовательского виджета не будут доступны до тех пор, пока load() не вернёт значение.

domXml() Описание свойств виджета, таких как его имя объекта, подсказка размера и другие стандартные свойства QWidget.
codeTemplate() Эта функция зарезервирована для будущего использования Qt Designer.

Также можно переопределить две другие виртуальные функции:

initialize() Настройка расширений и других функций для пользовательских виджетов. Расширения пользовательских контейнеров (см. QDesignerContainerExtension) и расширения меню задач (см. QDesignerTaskMenuExtension) должны быть настроены в этой функции.
isInitialized() Возвращает true, если виджет был инициализирован; в противном случае возвращает false. Переопределения обычно проверяют, была ли вызвана функция initialize(), и возвращают результат этой проверки.

Примечания к функции domXml()

Функция domXml() возвращает фрагмент файла UI, который используется фабрикой виджетов Qt Designer для создания пользовательского виджета и его соответствующих свойств.

Начиная с Qt 4.4, поле виджетов Qt Designer позволяет полностью описать один пользовательский виджет в файле UI. Файл UI можно загрузить с помощью тега <ui>. Указание тега <ui> позволяет добавить элемент <customwidget>, содержащий дополнительную информацию для пользовательских виджетов. Тег <widget> достаточен, если дополнительная информация не требуется.

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

    ...
R"(
    <property name="geometry">
      <rect>
        <x>0</x>
        <y>0</y>
        <width>100</width>
        <height>100</height>
      </rect>
    </property>
")
    ...

Дополнительная функция функции domXml() заключается в том, что если она возвращает пустую строку, виджет не будет установлен в поле виджетов Qt Designer. Однако он всё ещё может быть использован другими виджетами в форме. Эта функция используется для скрытия виджетов, которые не должны быть явно созданы пользователем, но необходимы другим виджетам.

Полное описание пользовательского виджета выглядит так:

<ui language="c++"> displayname="MyWidget">
    <widget class="widgets::MyWidget" name="mywidget"/>
    <customwidgets>
        <customwidget>
            <class>widgets::MyWidget</class>
            <addpagemethod>addPage</addpagemethod>
            <propertyspecifications>
                <stringpropertyspecification name="fileName" notr="true" type="singleline"/>
                <stringpropertyspecification name="text" type="richtext"/>
                <tooltip name="text">Explanatory text to be shown in Property Editor</tooltip>
            </propertyspecifications>
        </customwidget>
    </customwidgets>
</ui>

Атрибуты тега <ui>:

Атрибут Наличие Значения Комментарий
language необязательно "c++", "jambi" Этот атрибут указывает язык, для которого предназначен пользовательский виджет. Он главным образом служит для предотвращения появления C++-плагинов в Qt Jambi.
displayname необязательно Имя класса Значение атрибута отображается в поле «Виджет» и может использоваться для удаления имен пространств имён.

Тег <addpagemethod> сообщает Qt Designer и uic, какой метод следует использовать для добавления страниц в контейнерный виджет. Это относится к контейнерным виджетам, которые требуют вызова определённого метода для добавления дочернего элемента, а не добавления дочернего элемента путём передачи родителя. В частности, это актуально для контейнеров, которые не являются подклассом контейнеров, предоставляемых Qt Designer, но основаны на понятии «Текущая страница». Кроме того, вам нужно предоставить расширение контейнера для них.

Элемент <propertyspecifications> может содержать список метаинформации о свойствах.

Тег <tooltip> может использоваться для задания всплывающей подсказки, отображаемой в редакторе свойств при наведении курсора на свойство. Имя свойства указывается в атрибуте name, а текст элемента — это всплывающая подсказка. Эта функция была добавлена в Qt 5.6.

Для свойств типа строка можно использовать тег <stringpropertyspecification>. У этого тега есть следующие атрибуты:

Атрибут Наличие Значения Комментарий
name обязательно Имя свойства
type обязательно См. таблицу ниже Значение атрибута определяет, как редактор свойств будет обрабатывать их.
notr необязательно "true", "false" Если атрибут равен "true", значение не предназначено для перевода.

Значения атрибута type свойства типа строка:

Значение Тип
"richtext" Форматированный текст.
"multiline" Многострочный простой текст.
"singleline" Однострочный простой текст.
"stylesheet" CSS-стилевая таблица.
"objectname" Имя объекта (ограниченный набор допустимых символов).
"url" URL, имя файла.

Требования к плагинам

Для правильной работы плагинов на всех платформах необходимо убедиться, что они экспортируют необходимые Qt Designer символы.

Прежде всего, класс плагина должен быть экспортирован, чтобы плагин мог быть загружен Qt Designer. Для этого используйте макрос Q_PLUGIN_METADATA(). Также необходимо использовать макрос QDESIGNER_WIDGET_EXPORT для определения каждого класса пользовательского виджета внутри плагина, который Qt Designer будет инстанциировать.

Создание корректных виджетов

Некоторые пользовательские виджеты имеют особые функции пользовательского интерфейса, которые могут заставить их вести себя иначе по сравнению со многими стандартными виджетами, доступными в Qt Designer. В частности, если пользовательский виджет захватывает клавиатуру в результате вызова QWidget::grabKeyboard(), работа Qt Designer будет затронута.

Чтобы обеспечить специальное поведение пользовательских виджетов в Qt Designer, предоставьте реализацию функции initialize() для настройки процесса построения виджета под специфические требования Qt Designer. Эта функция будет вызвана в первый раз перед любыми вызовами createWidget() и, возможно, установит внутренний флаг, который может быть проверен позднее, когда Qt Designer вызовет функцию createWidget() плагина.

Компиляция и установка плагина

Простой плагин

Пример плагина пользовательского виджета Custom Widget Plugin Example демонстрирует простой плагин Qt Designer.

Файл .pro для плагина должен указывать заголовки и исходные файлы как для пользовательского виджета, так и для интерфейса плагина. Обычно этот файл только указывает, что проект плагина должен быть скомпилирован как библиотека, но с конкретной поддержкой плагинов для Qt Designer. Это делается с помощью следующих объявлений:

QT          += widgets uiplugin
CONFIG      += plugin
TEMPLATE    = lib

Переменная QT содержит ключевое слово uiplugin. Это указывает, что плагин использует только абстрактные интерфейсы QDesignerCustomWidgetInterface и QDesignerCustomWidgetCollectionInterface и не имеет связи с библиотеками Qt Designer. При обращении к другим интерфейсам Qt Designer, которые имеют связь, следует использовать designer; это гарантирует, что плагин динамически подключается к библиотекам Qt Designer и имеет отложенную зависимость от них.

Если плагины созданы в режиме, несовместимом с Qt Designer, они не будут загружены и установлены. Для получения дополнительной информации о плагинах см. документ Плагины HOWTO.

Также необходимо убедиться, что плагин установлен вместе с другими плагинами виджетов Qt Designer:

target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += target

Переменная $[QT_INSTALL_PLUGINS] является плейсхолдером для расположения установленных плагинов Qt. Вы можете настроить Qt Designer на поиск плагинов в других расположениях, установив переменную окружения QT_PLUGIN_PATH перед запуском приложения.

Примечание: Qt Designer будет искать подкаталог designer в каждом указанном пути.

См. QCoreApplication::libraryPaths() для получения дополнительной информации о настройке путей для библиотек и плагинов в приложениях Qt.

Разделение плагина

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

Следующие разделы описывают, как это исправить.

Связывание виджета с приложением

Исходный и заголовочный файлы пользовательского виджета могут быть совместно использованы приложением и Qt Designer путём создания файла .pri для включения:

INCLUDEPATH += $$PWD
HEADERS += $$PWD/analogclock.h
SOURCES += $$PWD/analogclock.cpp

Затем этот файл будет включен в файл .pro плагина и приложение:

include(customwidget.pri)

Использование виджета с помощью библиотеки

Другой подход заключается в размещении виджета в библиотеке, которая связана как с плагином Qt Designer, так и с приложением. Рекомендуется использовать статические библиотеки, чтобы избежать проблем с поиском библиотеки во время выполнения.

Для динамических библиотек см. Создание динамических библиотек.

Использование плагина с QUiLoader

Предпочтительный способ добавления пользовательских виджетов в QUiLoader — это наследование от него с переопределением QUiLoader::createWidget().

Однако также можно использовать пользовательские плагины виджетов Qt Designer (см. QUiLoader::pluginPaths() и связанные функции). Чтобы избежать необходимости развертывания библиотек Qt Designer на целевом устройстве, эти плагины не должны иметь связи с библиотеками Qt Designer (QT = uiplugin, см. Создание пользовательских виджетов для Qt Designer#BuildingandInstallingthePlugin).

Связанные примеры

Для получения дополнительной информации об использовании пользовательских виджетов в Qt Designer, обратитесь к примерам Плагин пользовательского виджета и Плагин мирового времени для получения дополнительной информации об использовании пользовательских виджетов в Qt Designer. Также можно использовать класс QDesignerCustomWidgetCollectionInterface для объединения нескольких пользовательских виджетов в одну библиотеку.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.2/designer-creating-custom-widgets.html

Spec-Zone.ru

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