Benutzerdefiniertes Widget-Plugin
Erstellen eines benutzerdefinierten Widget-Plugins für Qt Widgets Designer.
In diesem Beispiel basiert das benutzerdefinierte Widget auf dem Beispiel der Analoguhr und bietet keine benutzerdefinierten Signale oder Slots.
Vorbereitung
Um ein benutzerdefiniertes Widget bereitzustellen, das mit Qt Widgets Designer verwendet werden kann, müssen wir eine in sich geschlossene Implementierung und eine Plugin-Schnittstelle bereitstellen. In diesem Beispiel wird der Einfachheit halber das Analog Clock-Beispiel wiederverwendet.
Projektdateien
CMake
In den Projektdateien muss angegeben werden, dass ein Plugin erstellt werden soll, das mit den Bibliotheken von Qt Widgets Designer verknüpft ist:
find_package(Qt6 REQUIRED COMPONENTS Core Gui UiPlugin Widgets) qt_add_plugin(customwidgetplugin) target_link_libraries(customwidgetplugin PUBLIC Qt::Core Qt::Gui Qt::UiPlugin Qt::Widgets )
In der Liste der Link-Bibliotheken ist Qt::UiPlugin
angegeben. Dies zeigt an, dass das Plugin nur die abstrakten Schnittstellen QDesignerCustomWidgetInterface und QDesignerCustomWidgetCollectionInterface verwendet und keine Verknüpfung zu den Qt Widgets Designer-Bibliotheken hat. Beim Zugriff auf andere Schnittstellen von Qt Widgets Designer, die eine Verknüpfung haben, sollte stattdessen Designer
verwendet werden; dadurch wird sichergestellt, dass das Plugin dynamisch auf die Qt Widgets Designer-Bibliotheken verlinkt und eine Laufzeitabhängigkeit von ihnen hat.
Das folgende Beispiel zeigt, wie Sie die Header- und Quelldateien des Widgets hinzufügen:
target_sources(customwidgetplugin PRIVATE analogclock.cpp analogclock.h customwidgetplugin.cpp customwidgetplugin.h )
Wir stellen eine Implementierung der Plugin-Schnittstelle zur Verfügung, damit Qt Widgets Designer das benutzerdefinierte Widget verwenden kann.
Es ist auch wichtig, sicherzustellen, dass das Plugin an einem Ort installiert wird, der von Qt Widgets Designer durchsucht wird. Dazu geben wir einen Zielpfad für das Projekt an und fügen es der Liste der zu installierenden Elemente hinzu:
set(INSTALL_EXAMPLEDIR "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_PLUGINS}/designer") install(TARGETS customwidgetplugin RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" )
Das benutzerdefinierte Widget wird als Bibliothek erstellt. Es wird zusammen mit den anderen Qt Widgets Designer-Plugins installiert, wenn das Projekt installiert wird (mit ninja install
oder einem gleichwertigen Installationsverfahren).
Weitere Informationen über Plugins finden Sie in der Dokumentation How to Create Qt Plugins.
qmake
Das folgende Beispiel zeigt, wie man ein Plugin mit den Qt Widgets Designer-Bibliotheken verknüpft:
CONFIG += plugin TEMPLATE = lib QT += widgets uiplugin
Die Variable QT
enthält das Schlüsselwort uiplugin
, das der Bibliothek Qt::UiPlugin
entspricht.
Das folgende Beispiel zeigt, wie man die Header- und Quelldateien des Widgets hinzufügt:
HEADERS = analogclock.h \ customwidgetplugin.h SOURCES = analogclock.cpp \ customwidgetplugin.cpp OTHER_FILES += analogclock.json
Das folgende Beispiel zeigt, wie ein Plugin in den Plugin-Pfad des Qt Widgets Designers installiert wird:
TARGET = $$qtLibraryTarget($$TARGET) target.path = $$[QT_INSTALL_PLUGINS]/designer INSTALLS += target
AnalogClock Klassendefinition und -implementierung
Die Klasse AnalogClock
wird genau so definiert und implementiert wie im Analog Clock Beispiel beschrieben. Da die Klasse in sich geschlossen ist und keine externe Konfiguration erfordert, kann sie ohne Änderung als benutzerdefiniertes Widget im Qt Widgets Designer verwendet werden.
AnalogClockPlugin Klassendefinition
Die Klasse AnalogClock
ist für Qt Widgets Designer über die Klasse AnalogClockPlugin
zugänglich. Diese Klasse erbt sowohl von QObject als auch von der Klasse QDesignerCustomWidgetInterface und implementiert eine von QDesignerCustomWidgetInterface definierte Schnittstelle.
Um sicherzustellen, dass Qt das Widget als Plugin erkennt, exportieren Sie relevante Informationen über das Widget, indem Sie das Makro Q_PLUGIN_METADATA()
hinzufügen:
class AnalogClockPlugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface") Q_INTERFACES(QDesignerCustomWidgetInterface) public: explicit AnalogClockPlugin(QObject *parent = nullptr); bool isContainer() const override; bool isInitialized() const override; QIcon icon() const override; QString domXml() const override; QString group() const override; QString includeFile() const override; QString name() const override; QString toolTip() const override; QString whatsThis() const override; QWidget *createWidget(QWidget *parent) override; void initialize(QDesignerFormEditorInterface *core) override; private: bool initialized = false; };
Die Funktionen liefern Informationen über das Widget, die Qt Widgets Designer in der Widgetbox verwenden kann. Die private Member-Variable initialized
wird verwendet, um aufzuzeichnen, ob das Plugin von Qt Widgets Designer initialisiert wurde.
Beachten Sie, dass der einzige Teil der Klassendefinition, der für dieses spezielle benutzerdefinierte Widget spezifisch ist, der Klassenname ist.
AnalogClockPlugin Implementierung
Der Klassenkonstruktor ruft einfach den Konstruktor der Basisklasse QObject auf und setzt die Variable initialized
auf false
.
Qt Widgets Der Designer initialisiert das Plugin, wenn es benötigt wird, indem er die Funktion initialize()
aufruft:
void AnalogClockPlugin::initialize(QDesignerFormEditorInterface * /* core */) { if (initialized) return; initialized = true; }
In diesem Beispiel wird die private Variable initialized
getestet und nur dann auf true
gesetzt, wenn das Plugin nicht bereits initialisiert ist. Obwohl dieses Plugin keinen speziellen Code benötigt, der bei seiner Initialisierung ausgeführt wird, könnten wir einen solchen Code nach dem Test auf Initialisierung einfügen.
Die Funktion isInitialized()
teilt dem Qt Widgets Designer mit, ob das Plugin einsatzbereit ist:
bool AnalogClockPlugin::isInitialized() const { return initialized; }
Die Instanzen des benutzerdefinierten Widgets werden von der Funktion createWidget()
bereitgestellt. Die Implementierung für die analoge Uhr ist einfach:
In diesem Fall muss für das benutzerdefinierte Widget nur parent
angegeben werden. Wenn andere Argumente für das Widget benötigt werden, können sie hier eingegeben werden.
Die folgenden Funktionen liefern Informationen für Qt Widgets Designer, die zur Darstellung des Widgets in der Widgetbox verwendet werden. Die Funktion name()
gibt den Namen der Klasse zurück, die das benutzerdefinierte Widget bereitstellt:
QString AnalogClockPlugin::name() const { return u"AnalogClock"_s; }
Die Funktion group()
wird verwendet, um den Typ des Widgets zu beschreiben, zu dem das benutzerdefinierte Widget gehört:
QString AnalogClockPlugin::group() const { return u"Display Widgets [Examples]"_s; }
Das Widget-Plugin wird in einem Abschnitt platziert, der durch seinen Gruppennamen im Widget-Feld von Qt Widgets Designer identifiziert wird. Das Symbol, das zur Darstellung des Widgets in der Widgetbox verwendet wird, wird von der Funktion icon()
zurückgegeben:
QIcon AnalogClockPlugin::icon() const { return {}; }
In diesem Fall geben wir ein Null-Symbol zurück, um anzuzeigen, dass wir kein Symbol haben, das zur Darstellung des Widgets verwendet werden kann.
Für den Eintrag des benutzerdefinierten Widgets in der Widgetbox kann ein Tooltip und eine "Was ist das?"-Hilfe bereitgestellt werden. Die Funktion toolTip()
sollte eine kurze Nachricht zurückgeben, die das Widget beschreibt:
QString AnalogClockPlugin::toolTip() const { return {}; }
Die Funktion whatsThis()
kann eine längere Beschreibung zurückgeben:
QString AnalogClockPlugin::whatsThis() const { return {}; }
Die Funktion isContainer()
teilt Qt Widgets Designer mit, ob das Widget als Container für andere Widgets verwendet werden soll. Wenn nicht, wird Qt Widgets Designer dem Benutzer nicht erlauben, Widgets darin zu platzieren.
bool AnalogClockPlugin::isContainer() const { return false; }
Die meisten Widgets in Qt können untergeordnete Widgets enthalten, aber es macht nur Sinn, spezielle Container-Widgets für diesen Zweck in Qt Widgets Designer zu verwenden. Indem wir false
zurückgeben, zeigen wir an, dass das benutzerdefinierte Widget keine anderen Widgets enthalten kann. Wenn wir true zurückgeben würden, würde Qt Widgets Designer erlauben, dass andere Widgets innerhalb der analogen Uhr platziert werden und ein Layout definiert werden kann.
Die Funktion domXml()
bietet eine Möglichkeit, Standardeinstellungen für das Widget in das von Qt Widgets Designer verwendete Standard-XML-Format aufzunehmen. In diesem Fall geben wir nur die Geometrie des Widgets an:
QString AnalogClockPlugin::domXml() const { return uR"( <ui language="c++"> <widget class="AnalogClock" name="analogClock"> )" R"( <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>100</width> <height>100</height> </rect> </property> ") R"( <property name="toolTip"> <string>The current time</string> </property> <property name="whatsThis"> <string>The analog clock widget displays the current time.</string> </property> </widget> </ui> )"_s; }
Wenn das Widget einen vernünftigen Größenhinweis bietet, ist es nicht notwendig, diesen hier zu definieren. Die Rückgabe eines leeren Strings anstelle eines <widget>
-Elements weist Qt Widgets Designer außerdem an, das Widget nicht in die Widget-Box zu installieren.
Um das Analoguhr-Widget für Anwendungen nutzbar zu machen, implementieren wir die Funktion includeFile()
, die den Namen der Header-Datei zurückgibt, die die Definition der benutzerdefinierten Widget-Klasse enthält:
QString AnalogClockPlugin::includeFile() const { return u"analogclock.h"_s; }
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.