=> Главная База Знаний Qt Интеграция пользовательских виджетов в qt designer


Интеграция пользовательских виджетов в qt designer

Интеграция пользовательских виджетов в qt designer

Прежде чем мы сможем использовать пользовательские виджеты в Qt Designer, мы должны сделать так, что Qt Designer будет знать о них. Для этого существует два способа: метод «продвижения» (promotion) и метод подключения (plugin).

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

Ниже приводится порядок действий при интеграции данным методом виджета HexSpinBox:

1. Создайте наборный счетчик QSpinBox, перетаскивая его с панели виджетов Qt Designer на форму.

2. Щелкните правой клавишей мышки по наборному счетчику и выберите пункт контекстного меню Promote to Custom Widget (Преобразовать в пользовательский виджет).

3. Заполните в появившемся диалоговом окне поле названия класса значением «HexSpinBox» и поле заголовочного файла значением «hexspinbox.h».

Вот и все! Сгенерированный компилятором uic программный код будет содержать оператор #include hexspinbox.h вместо <QSpinBox> и будет инстанцировать HexSpinBox. В Qt Designer виджет HexSpinBox будет представлен виджетом QSpinBox, позволяя нам устанавливать любые свойства QSpinBox (например, допустимый диапазон значений и текущее значение).

Рис. 5.6. Диалоговое окно для создания пользовательских виджетов Qt Designer.

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

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

Во-первых, мы должны создать подкласс QDesignerCustomWidgetInterface и переопределить несколько виртуальных функций. Мы предположим, что исходный файл подключаемого модуля расположен в каталоге с именем iconeditorplugin, а исходный текст программы IconEditor расположен в параллельном каталоге с именем iconeditor.

Ниже приводится определение класса:

01 #include <QDesignerCustomWidgetInterface>

02 class IconEditorPlugin : public QObject,

03 public QDesignerCustomWidgetInterface

04 {

05 Q_OBJECT

06 Q_INTERFACES(QDesignerCustomWidgetInterface)

07 public:

08 IconEditorPlugin(QObject *parent = 0);

09 QString name() const;

10 QString includeFile() const;

11 QString group() const;

12 QIcon icon() const;

13 QString toolTip() const;

14 QString whatsThis() const;

15 bool isContainer() const;

16 QWidget *createWidget(QWidget *parent);

17 };

Подкласс IconEditorPlugin является фабрикой класса (factory class), который инкапсулирует виджет IconEditor. Он является наследником классов QObject и QDesignerCustomWidgetIterface и использует макрос Q_INTERFACES(), указывая компилятору moc на то, что второй базовый класс представляет собой подключаемый интерфейс. Его функции применяются Qt Designer для создания экземпляров класса и получения информации о нем.

01 IconEditorPlugin::IconEditorPlugin(QObject *parent)

02 : QObject(parent)

03 {

04 }

IconEditorPlugin имеет тривиальный конструктор.

05 QString IconEditorPlugin::name() const

06 {

07 return "IconEditor";

08 }

Функция name() возвращает имя подключаемого виджета.

09 QString IconEditorPlugin::includeFile() const

10 {

11 return "iconeditor.h";

12 }

Функция includeFile() возвращает имя заголовочного файла для заданного виджета, который инкапсулирован в подключаемом модуле. Заголовочный файл включается в программный код, сгенерированный компилятором uic.

13 QString IconEditorPlugin::group() const

14 {

15 return tr("Image Manipulation Widgets");

16 }

Функция group() возвращает имя группы на панели виджетов, к которой принадлежит пользовательский виджет. Если это имя еще не используется, Qt Designer coздаст новую группу для виджета.

17 QIcon IconEditorPlugin::icon() const

18 {

19 return QIcon(":/images/iconeditor.png");

20 }

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

21 QString IconEditorPlugin::toolTip() const

22 {

23 return tr("An icon editor widget");

24 }

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

25 QString IconEditorPlugin::whatsThis() const

26 {

27 return tr("This widget is presented in Chapter 5 of <i>C++ GUI "

28 "Programming with Qt 4</i> as an example of a custom Qt "

29 "widget.");

30 }

Функция whatsThis() возвращает текст «What's This?» (что это?) для отображения в Qt Designer.

31 bool IconEditorPlugin::isContainer() const

32 {

33 return false;

34 }

Функция isContainer() возвращает true, если данный виджет может содержать другие виджеты; в противном случае он возвращает false. Например, QFrame представляет собой виджет, который может содержать другие виджеты. В целом любой виджет может содержать другие виджеты, но Qt Designer не позволяет это делать, если isContainer() возвращает false.

35 QWidget *IconEditorPlugin::createWidget(QWidget *parent)

36 {

37 return new IconEditor(parent);

38 }

Функция createWidget() вызывается Qt Designer для создания экземпляра класса виджета для указанного родительского виджета.

39 Q_EXPORT_PLUGIN2(iconeditorplugin, IconEditorPlugin)

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

Используемый для построения подключаемого модуля файл .pго выглядит следующим образом:

TEMPLATE = lib

CONFIG += designer plugin release

HEADERS = ../iconeditor/iconeditor.h \

iconeditorplugin.h

SOURCES = ../iconeditor/iconeditor.cpp \

iconeditorplugin.cpp

RESOURCES = iconeditorplugin.qrc

DESTDIR = $(QTDIR)/plugins/designer

Файл .pro предполагает, что переменная окружения QTDIR установлена на каталог, где располагается Qt. Когда вы вводите команду make или nmake для построения подключаемого модуля, он автоматически устанавливается в каталог plugins Qt Designer. Поле построения подключаемого модуля виджет IconEditor мoжeт использоваться в Qt Designer таким же образом как, любые встроенные виджеты Qt.

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