Spec-Zone.ru › Qt 5.11

Создание пользовательских виджетов для 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 определяет геометрию виджета по умолчанию следующим образом:

    ...
           "  <property name=\"geometry\">\n"
           "   <rect>\n"
           "    <x>0</x>\n"
           "    <y>0</y>\n"
           "    <width>100</width>\n"
           "    <height>100</height>\n"
           "   </rect>\n"
           "  </property>\n"
    ...

Дополнительная возможность функции 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 демонстрирует простой плагин 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, они не будут загружены и установлены. Дополнительную информацию о плагинах можно найти в документе Plugins 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/archives/qt-5.11/designer-creating-custom-widgets.html

Spec-Zone.ru

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