Erstellen von benutzerdefinierten Widgets für Qt Widgets Designer

Qt Widgets Die Plugin-basierte Architektur von Designer ermöglicht es, benutzerdefinierte Widgets und benutzerdefinierte Widgets von Drittanbietern genauso zu bearbeiten, wie Sie es mit Standard-Qt Widgets tun. Alle Funktionen des benutzerdefinierten Widgets werden Qt Widgets Designer zur Verfügung gestellt, einschließlich Widget-Eigenschaften, Signale und Slots. Da Qt Widgets Designer während des Formularentwurfsprozesses echte Widgets verwendet, werden benutzerdefinierte Widgets genauso angezeigt wie in der Vorschau.

Das Modul QtDesigner bietet Ihnen die Möglichkeit, benutzerdefinierte Widgets in Qt Widgets Designer zu erstellen.

Erste Anfänge

Um ein benutzerdefiniertes Widget in Qt Widgets Designer zu integrieren, benötigen Sie eine passende Beschreibung für das Widget und eine entsprechende Projektdatei.

Bereitstellen einer Schnittstellenbeschreibung

Um Qt Widgets Designer über die Art des Widgets zu informieren, das Sie anbieten möchten, erstellen Sie eine Unterklasse von QDesignerCustomWidgetInterface, die die verschiedenen Eigenschaften Ihres Widgets beschreibt. Die meisten dieser Eigenschaften werden von Funktionen bereitgestellt, die in der Basisklasse rein virtuell sind, da nur der Autor des Plugins diese Informationen bereitstellen kann.

FunktionBeschreibung des Rückgabewerts
name()Der Name der Klasse, die das Widget bereitstellt.
group()Die Gruppe in der Widget-Box von Qt Widgets Designer, zu der das Widget gehört.
toolTip()Eine kurze Beschreibung, die Benutzern hilft, das Widget in Qt Widgets Designer zu identifizieren.
whatsThis()Eine längere Beschreibung des Widgets für Benutzer von Qt Widgets Designer.
includeFile()Die Header-Datei, die in Anwendungen, die dieses Widget verwenden, enthalten sein muss. Diese Informationen werden in UI-Dateien gespeichert und von uic verwendet, um eine geeignete #includes -Anweisung im Code zu erstellen, der für das Formular mit dem benutzerdefinierten Widget generiert wird.
icon()Ein Symbol, das zur Darstellung des Widgets in der Widget-Box von Qt Widgets Designer verwendet werden kann.
isContainer()True, wenn das Widget verwendet wird, um untergeordnete Widgets zu enthalten; andernfalls false.
createWidget()Ein QWidget Zeiger auf eine Instanz des benutzerdefinierten Widgets, konstruiert mit dem übergebenen Elternteil.

Hinweis: createWidget() ist eine Factory-Funktion, die nur für die Erstellung des Widgets verantwortlich ist. Die Eigenschaften des benutzerdefinierten Widgets sind nicht verfügbar, bis load() zurückkehrt.

domXml()Eine Beschreibung der Eigenschaften des Widgets, wie z.B. der Objektname, der Hinweis auf die Größe und andere Standard-Eigenschaften QWidget.
codeTemplate()Diese Funktion ist für die zukünftige Verwendung durch Qt Widgets Designer reserviert.

Zwei weitere virtuelle Funktionen können ebenfalls reimplementiert werden:

initialize()Richtet Erweiterungen und andere Funktionen für benutzerdefinierte Widgets ein. Benutzerdefinierte Container-Erweiterungen (siehe QDesignerContainerExtension) und Taskmenü-Erweiterungen (siehe QDesignerTaskMenuExtension) sollten in dieser Funktion eingerichtet werden.
isInitialized()Gibt true zurück, wenn das Widget initialisiert wurde; andernfalls wird false zurückgegeben. Neuimplementierungen prüfen in der Regel, ob die Funktion initialize() aufgerufen wurde und geben das Ergebnis dieser Prüfung zurück.

Hinweise zur Funktion domXml()

Die Funktion domXml() gibt ein UI-Datei-Snippet zurück, das von der Widget-Factory des Qt Widgets Designers verwendet wird, um ein benutzerdefiniertes Widget und seine entsprechenden Eigenschaften zu erstellen.

Seit Qt 4.4 ermöglicht die Widget-Box von Qt Widgets Designer eine komplette UI-Datei zur Beschreibung eines benutzerdefinierten Widgets. Die UI-Datei kann mit dem <ui> Tag geladen werden. Die Angabe des <ui>-Tags ermöglicht das Hinzufügen des <customwidget>-Elements, das zusätzliche Informationen für benutzerdefinierte Widgets enthält. Der <widget> -Tag ist ausreichend, wenn keine zusätzlichen Informationen erforderlich sind.

Wenn das benutzerdefinierte Widget keinen vernünftigen Größenhinweis bietet, ist es notwendig, eine Standardgeometrie in der Zeichenkette anzugeben, die von der Funktion domXml() in Ihrer Unterklasse zurückgegeben wird. Zum Beispiel definiert die AnalogClockPlugin, die vom Custom Widget Plugin Beispiel zur Verfügung gestellt wird, eine Standard-Widgetgeometrie auf die folgende Weise:

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

Ein zusätzliches Merkmal der Funktion domXml() ist, dass das Widget nicht in der Widgetbox von Qt Widgets Designer installiert wird, wenn sie einen leeren String zurückgibt. Es kann jedoch weiterhin von anderen Widgets im Formular verwendet werden. Diese Funktion wird verwendet, um Widgets auszublenden, die nicht explizit vom Benutzer erstellt werden sollen, aber von anderen Widgets benötigt werden.

Eine vollständige Spezifikation eines benutzerdefinierten Widgets sieht so aus:

<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>

Attribute des <ui> Tags:

AttributAnwesenheitWerteKommentar
languageoptional"c++", "jambi"Dieses Attribut gibt die Sprache an, für die das benutzerdefinierte Widget bestimmt ist. Es ist hauptsächlich dazu da, um zu verhindern, dass C++-Plugins in Qt Jambi auftauchen.
displaynameoptionalKlassennameDer Wert des Attributs erscheint in der Widget-Box und kann verwendet werden, um Namespaces zu entfernen.

Das <addpagemethod> Tag teilt Qt Widgets Designer und uic mit, welche Methode verwendet werden soll, um Seiten zu einem Container-Widget hinzuzufügen. Dies gilt für Container-Widgets, die den Aufruf einer bestimmten Methode erfordern, um ein Kind hinzuzufügen, anstatt das Kind durch Übergabe des Elternteils hinzuzufügen. Dies ist insbesondere für Container relevant, die keine Unterklasse der in Qt Widgets Designer bereitgestellten Container sind, sondern auf dem Konzept der aktuellen Seite basieren. Darüber hinaus müssen Sie eine Container-Erweiterung für sie bereitstellen.

Das Element <propertyspecifications> kann eine Liste von Eigenschafts-Meta-Informationen enthalten.

Das Tag <tooltip> kann verwendet werden, um einen Tooltip anzugeben, der im Eigenschaftseditor angezeigt wird, wenn der Mauszeiger über die Eigenschaft bewegt wird. Der Eigenschaftsname wird im Attribut name angegeben und der Elementtext ist der Tooltip. Diese Funktionalität wurde in Qt 5.6 hinzugefügt.

Für Eigenschaften vom Typ String kann das Tag <stringpropertyspecification> verwendet werden. Dieses Tag hat die folgenden Attribute:

AttributVorhandenseinWerteKommentar
nameerforderlichName der Eigenschaft
typeerforderlichSiehe Tabelle untenDer Wert des Attributs bestimmt, wie der Eigenschaftseditor mit ihnen umgehen wird.
notroptional"wahr", "falsch"Wenn das Attribut "true" ist, soll der Wert nicht übersetzt werden.

Werte des Attributs type der Eigenschaft string:

WertTyp
"richtext"Reichhaltiger Text.
"multiline"Mehrzeiliger einfacher Text.
"singleline"Einzeiliger einfacher Text.
"stylesheet"Ein Blatt im CSS-Stil.
"objectname"Ein Objektname (eingeschränkter Satz gültiger Zeichen).
"url"URL, Dateiname.

Plugin-Anforderungen

Damit Plugins auf allen Plattformen korrekt funktionieren, müssen Sie sicherstellen, dass sie die von Qt Widgets Designer benötigten Symbole exportieren.

Zuallererst muss die Plugin-Klasse exportiert werden, damit das Plugin von Qt Widgets Designer geladen werden kann. Verwenden Sie dazu das Makro Q_PLUGIN_METADATA(). Außerdem muss das Makro QDESIGNER_WIDGET_EXPORT verwendet werden, um jede benutzerdefinierte Widget-Klasse innerhalb eines Plugins zu definieren, die Qt Widgets Designer instanziieren wird.

Wohlverhaltende Widgets erstellen

Einige benutzerdefinierte Widgets haben spezielle Eigenschaften der Benutzeroberfläche, die dazu führen können, dass sie sich anders verhalten als viele der Standard-Widgets in Qt Widgets Designer. Insbesondere, wenn ein benutzerdefiniertes Widget die Tastatur als Ergebnis eines Aufrufs von QWidget::grabKeyboard() ergreift, wird der Betrieb von Qt Widgets Designer beeinflusst.

Um benutzerdefinierten Widgets ein spezielles Verhalten in Qt Widgets Designer zu geben, stellen Sie eine Implementierung der Funktion initialize() bereit, um den Widget-Erstellungsprozess für Qt Widgets Designer-spezifisches Verhalten zu konfigurieren. Diese Funktion wird zum ersten Mal vor allen Aufrufen von createWidget() aufgerufen und könnte vielleicht ein internes Flag setzen, das später getestet werden kann, wenn Qt Widgets Designer die createWidget() Funktion des Plugins aufruft.

Erstellen und Installieren des Plugins

Ein einfaches Plugin

Das Custom Widget Plugin demonstriert ein einfaches Qt Widgets Designer Plugin.

Die Projektdatei für ein Plugin muss die Header und Quellen sowohl für das benutzerdefinierte Widget als auch für die Plugin-Schnittstelle angeben. Normalerweise muss in dieser Datei nur angegeben werden, dass das Projekt des Plugins als Bibliothek erstellt wird, aber mit spezifischer Plugin-Unterstützung für Qt Widgets Designer. Für CMake wird dies mit den folgenden Deklarationen gemacht:

find_package(Qt6 REQUIRED COMPONENTS Core Gui UiPlugin Widgets)

qt_add_plugin(customwidgetplugin)
target_sources(customwidgetplugin PRIVATE
    analogclock.cpp analogclock.h
    customwidgetplugin.cpp customwidgetplugin.h
)
target_link_libraries(customwidgetplugin PUBLIC
    Qt::Core
    Qt::Gui
    Qt::UiPlugin
    Qt::Widgets
)

In der Link-Library-Liste wird 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.

Es muss auch sichergestellt werden, dass das Plugin zusammen mit anderen Qt Widgets Designer Widget-Plugins installiert wird:

   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}"
)

Für qmake:

CONFIG      += plugin
TEMPLATE    = lib
HEADERS     = analogclock.h \
              customwidgetplugin.h
SOURCES     = analogclock.cpp \
              customwidgetplugin.cpp
OTHER_FILES += analogclock.json

Die Variable QT enthält das Schlüsselwort uiplugin, das der Bibliothek Qt::UiPlugin entspricht.

Es muss auch sichergestellt werden, dass das Plugin zusammen mit anderen Qt Widgets Designer Widget Plugins installiert wird:

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

Die Variable $[QT_INSTALL_PLUGINS] ist ein Platzhalter für den Ort der installierten Qt-Plugins. Sie können Qt Widgets Designer so konfigurieren, dass er an anderen Orten nach Plugins sucht, indem Sie die Umgebungsvariable QT_PLUGIN_PATH setzen, bevor Sie die Anwendung ausführen.

Hinweis: Qt Widgets Designer sucht in jedem angegebenen Pfad nach einem Unterverzeichnis designer.

Siehe QCoreApplication::libraryPaths() für weitere Informationen über die Anpassung von Pfaden für Bibliotheken und Plugins mit Qt-Anwendungen.

Wenn Plugins in einem Modus erstellt werden, der nicht mit Qt Widgets Designer kompatibel ist, werden sie nicht geladen und installiert. Weitere Informationen über Plugins finden Sie im Plugins HOWTO Dokument.

Aufteilung des Plugins

Der oben erläuterte einfache Ansatz führt zu einem Problem, insbesondere bei der Verwendung der anderen Schnittstellen von Qt Widgets Designer, die eine Verknüpfung aufweisen: Die Anwendung, die das benutzerdefinierte Widget verwendet, ist dann von Qt Widgets Designer Headern und Bibliotheken abhängig. In einem realen Szenario ist dies nicht erwünscht.

Die folgenden Abschnitte beschreiben, wie dieses Problem gelöst werden kann.

Verknüpfung des Widgets mit der Anwendung

Bei der Verwendung von qmake können die Quell- und Header-Datei des benutzerdefinierten Widgets von der Anwendung und dem Qt Widgets Designer gemeinsam genutzt werden, indem eine .pri Datei zur Einbindung erstellt wird:

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

Diese Datei wird dann in die .pro Datei des Plugins und der Anwendung eingebunden:

include(customwidget.pri)

Bei der Verwendung von CMake können die Quelldateien des Widgets auf ähnliche Weise zum Anwendungsprojekt hinzugefügt werden.

Gemeinsame Nutzung des Widgets mit einer Bibliothek

Ein anderer Ansatz besteht darin, das Widget in eine Bibliothek einzubinden, die sowohl mit dem Qt Widgets Designer Plugin als auch mit der Anwendung verknüpft ist. Es wird empfohlen, statische Bibliotheken zu verwenden, um Probleme beim Auffinden der Bibliothek zur Laufzeit zu vermeiden.

Für gemeinsam genutzte Bibliotheken siehe Erstellen von gemeinsam genutzten Bibliotheken.

Verwendung des Plugins mit QUiLoader

Die bevorzugte Methode, um QUiLoader benutzerdefinierte Widgets hinzuzufügen, besteht darin, die Subklasse QUiLoader::createWidget() neu zu implementieren.

Es ist jedoch auch möglich, Qt Widgets Designer benutzerdefinierte Widget-Plugins zu verwenden (siehe QUiLoader::pluginPaths() und verwandte Funktionen). Um zu vermeiden, dass die Qt Widgets Designer-Bibliotheken auf dem Zielgerät installiert werden müssen, sollten diese Plugins keine Verknüpfung zu den Qt Widgets Designer-Bibliotheken haben (QT = uiplugin, siehe Erstellen von benutzerdefinierten Widgets für Qt Widgets Designer#BuildingandInstallingthePlugin).

Weitere Informationen zur Verwendung von benutzerdefinierten Widgets in Qt Widgets Designer finden Sie in den Beispielen für das benutzerdefinierte Widget-Plugin und die Aufgabenmenüerweiterung für weitere Informationen zur Verwendung von benutzerdefinierten Widgets in Qt Widgets Designer. Sie können auch die Klasse QDesignerCustomWidgetCollectionInterface verwenden, um mehrere benutzerdefinierte Widgets in einer einzigen Bibliothek zu kombinieren.

© 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.