Spec-Zone.ru › Qt 5.9

Создание пользовательских виджетов для 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() плагина.

Сборка и установка плагина

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

Пример плагина пользовательского виджета демонстрирует простой плагин 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/qt-5.9/designer-creating-custom-widgets.html

Spec-Zone.ru

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