Beispiel für eine Container-Erweiterung
Erstellen eines benutzerdefinierten mehrseitigen Plugins für Qt Widgets Designer.
Das Container Extension Beispiel zeigt, wie man ein benutzerdefiniertes mehrseitiges Plugin für Qt Widgets Designer unter Verwendung der QDesignerContainerExtension Klasse erstellt.
Um ein benutzerdefiniertes Widget bereitzustellen, das mit Qt Widgets Designer verwendet werden kann, müssen wir eine in sich geschlossene Implementierung bereitstellen. In diesem Beispiel verwenden wir ein benutzerdefiniertes mehrseitiges Widget, das die Container-Erweiterungsfunktion anzeigt.
Eine Erweiterung ist ein Objekt, das das Verhalten von Qt Widgets Designer modifiziert. QDesignerContainerExtension ermöglicht es Qt Widgets Designer, ein benutzerdefiniertes mehrseitiges Widget zu verwalten und zu manipulieren, d. h. dem Widget Seiten hinzuzufügen und zu löschen.
Es gibt vier Arten von Erweiterungen in Qt Widgets Designer:
- QDesignerMemberSheetExtension bietet eine Erweiterung, die es Ihnen ermöglicht, die Mitgliedsfunktionen eines Widgets zu manipulieren, die bei der Konfiguration von Verbindungen mit dem Qt Widgets Designer-Modus zur Bearbeitung von Signalen und Slots angezeigt werden.
- QDesignerPropertySheetExtension bietet eine Erweiterung, die es Ihnen ermöglicht, die Eigenschaften eines Widgets zu bearbeiten, die im Eigenschaftseditor von Qt Widgets Designer angezeigt wird.
- QDesignerTaskMenuExtension bietet eine Erweiterung, mit der Sie benutzerdefinierte Menüeinträge zum Aufgabenmenü von Qt Widgets Designer hinzufügen können.
- QDesignerContainerExtension bietet eine Erweiterung, mit der Sie Seiten zu einem mehrseitigen Container-Plugin in Qt Widgets Designer hinzufügen (und löschen) können.
Sie können alle Erweiterungen nach dem gleichen Muster wie in diesem Beispiel verwenden, indem Sie nur die jeweilige Basisklasse der Erweiterung ersetzen. Für weitere Informationen, siehe Qt Widgets Designer C++ Classes.
Das Beispiel der Container-Erweiterung besteht aus vier Klassen:
MultiPageWidget
ist ein benutzerdefiniertes Container-Widget, das es dem Benutzer ermöglicht, seine Seiten zu manipulieren und zu füllen, und zwischen diesen mit Hilfe einer Combobox zu navigieren.MultiPageWidgetPlugin
stellt die KlasseMultiPageWidget
dem Qt Widgets Designer zur Verfügung.MultiPageWidgetExtensionFactory
erstellt einMultiPageWidgetContainerExtension
Objekt.MultiPageWidgetContainerExtension
stellt die Container-Erweiterung bereit.
Projektdateien für benutzerdefinierte Widget-Plugins benötigen einige zusätzliche Informationen, um sicherzustellen, dass sie in Qt Widgets Designer funktionieren. Zum Beispiel sind benutzerdefinierte Widget-Plugins auf Komponenten angewiesen, die mit Qt Widgets Designer geliefert werden, und dies muss in den Projektdateien, die wir verwenden, angegeben werden. Wir werden uns zunächst die Projektdateien des Plugins ansehen.
Danach werden wir uns die Klasse MultiPageWidgetPlugin
ansehen und einen Blick auf die Klassen MultiPageWidgetExtensionFactory
und MultiPageWidgetContainerExtension
werfen. Schließlich werfen wir einen kurzen Blick auf die Definition der Klasse MultiPageWidget
.
Projektdateien
CMake
In den Projektdateien muss angegeben werden, dass ein Plugin, das mit den Qt Widgets Designer-Bibliotheken verknüpft ist, erstellt werden soll:
find_package(Qt6 REQUIRED COMPONENTS Core Designer Gui Widgets) qt_add_plugin(containerextension) target_link_libraries(containerextension PUBLIC Qt::Core Qt::Designer Qt::Gui Qt::Widgets )
Das folgende Beispiel zeigt, wie man die Header- und Quelldateien des Widgets hinzufügt:
target_sources(containerextension PRIVATE multipagewidget.cpp multipagewidget.h multipagewidgetcontainerextension.cpp multipagewidgetcontainerextension.h multipagewidgetextensionfactory.cpp multipagewidgetextensionfactory.h multipagewidgetplugin.cpp multipagewidgetplugin.h )
Wir stellen eine Implementierung der Plugin-Schnittstelle zur Verfügung, damit Qt Widgets Designer das benutzerdefinierte Widget verwenden kann. In diesem speziellen Beispiel stellen wir auch Implementierungen der Container-Erweiterungsschnittstelle und der Erweiterungsfabrik bereit.
Es ist 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 containerextension RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" )
Die Container-Erweiterung wird als Bibliothek erstellt. Sie 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:
TEMPLATE = lib CONFIG += plugin QT += widgets designer
Das folgende Beispiel zeigt, wie man die Header- und Source-Dateien des Widgets hinzufügt:
HEADERS += multipagewidget.h \ multipagewidgetplugin.h \ multipagewidgetcontainerextension.h \ multipagewidgetextensionfactory.h SOURCES += multipagewidget.cpp \ multipagewidgetplugin.cpp \ multipagewidgetcontainerextension.cpp \ multipagewidgetextensionfactory.cpp OTHER_FILES += multipagewidget.json
Das folgende Beispiel zeigt, wie ein Plugin in den Plugin-Pfad des Qt Widgets Designers installiert wird:
target.path = $$[QT_INSTALL_PLUGINS]/designer INSTALLS += target
MultiPageWidgetPlugin Klassendefinition
Die Klasse MultiPageWidgetPlugin
stellt die Klasse MultiPageWidget
dem Qt Widgets Designer zur Verfügung. Ihre Definition ähnelt der Plugin-Klasse des Custom Widget Plugin-Beispiels, das im Detail erläutert wird. Die Teile der Klassendefinition, die für dieses spezielle benutzerdefinierte Widget spezifisch sind, sind der Klassenname und ein paar private Slots:
#ifndef MULTIPAGEWIDGETPLUGIN_H #define MULTIPAGEWIDGETPLUGIN_H #include <QtUiPlugin/QDesignerCustomWidgetInterface> class QIcon; class QWidget; class MultiPageWidgetPlugin: public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidget") Q_INTERFACES(QDesignerCustomWidgetInterface) public: explicit MultiPageWidgetPlugin(QObject *parent = nullptr); QString name() const override; QString group() const override; QString toolTip() const override; QString whatsThis() const override; QString includeFile() const override; QIcon icon() const override; bool isContainer() const override; QWidget *createWidget(QWidget *parent) override; bool isInitialized() const override; void initialize(QDesignerFormEditorInterface *formEditor) override; QString domXml() const override; private slots: void currentIndexChanged(int index); void pageTitleChanged(const QString &title); private: bool initialized = false; }; #endif
Die Plugin-Klasse versorgt Qt Widgets Designer mit grundlegenden Informationen über unser Plugin, wie dem Klassennamen und der Include-Datei. Außerdem weiß sie, wie man Instanzen des MultiPageWidget
Widgets erstellt. MultiPageWidgetPlugin
definiert auch die Funktion initialize(), die aufgerufen wird, nachdem das Plugin in Qt Widgets Designer geladen wurde. Der Parameter QDesignerFormEditorInterface der Funktion bietet dem Plugin einen Zugang zu allen APIs von Qt Widgets Designer.
Im Falle eines mehrseitigen Widgets wie dem unseren müssen wir auch zwei private Slots implementieren, currentIndexChanged() und pageTitleChanged(), um in der Lage zu sein, den Eigenschaftseditor von Qt Widgets Designer zu aktualisieren, wenn der Benutzer eine andere Seite ansieht oder einen der Seitentitel ändert. Um jeder Seite einen eigenen Titel geben zu können, haben wir uns entschieden, die Eigenschaft QWidget::windowTitle zu verwenden, um den Seitentitel zu speichern (für weitere Informationen siehe die Implementierung der Klasse MultiPageWidget in containerextension/multipagewidget.cpp. Beachten Sie, dass es derzeit keine Möglichkeit gibt, eine benutzerdefinierte Eigenschaft (z. B. einen Seitentitel) zu den Seiten hinzuzufügen, ohne eine vordefinierte Eigenschaft als Platzhalter zu verwenden.
Die Klasse MultiPageWidgetPlugin
erbt sowohl von QObject als auch von QDesignerCustomWidgetInterface. Es ist wichtig, bei der Verwendung von Mehrfachvererbung darauf zu achten, dass alle Schnittstellen (d.h. die Klassen, die nicht von Q_OBJECT erben) dem Meta-Objektsystem mit dem Makro Q_INTERFACES() bekannt gemacht werden. Dies ermöglicht es Qt Widgets Designer, qobject_cast() zu verwenden, um nach unterstützten Schnittstellen zu suchen, wobei nichts weiter als ein QObject Zeiger verwendet wird.
Um sicherzustellen, dass Qt das Widget als Plugin erkennt, exportieren Sie relevante Informationen über das Widget, indem Sie das Q_PLUGIN_METADATA()
Makro hinzufügen:
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidget")
Mit diesem Makro kann Qt Widgets Designer auf das benutzerdefinierte Widget zugreifen und es konstruieren. Ohne dieses Makro gibt es keine Möglichkeit für Qt Widgets Designer, das Widget zu verwenden.
Implementierung der MultiPageWidgetPlugin-Klasse
Die Implementierung der MultiPageWidgetPlugin-Klasse entspricht in den meisten Teilen der Plugin-Klasse des Custom Widget Plugin-Beispiels:
MultiPageWidgetPlugin::MultiPageWidgetPlugin(QObject *parent) : QObject(parent) { } QString MultiPageWidgetPlugin::name() const { return u"MultiPageWidget"_s; } QString MultiPageWidgetPlugin::group() const { return u"Display Widgets [Examples]"_s; } QString MultiPageWidgetPlugin::toolTip() const { return {}; } QString MultiPageWidgetPlugin::whatsThis() const { return {}; } QString MultiPageWidgetPlugin::includeFile() const { return u"multipagewidget.h"_s; } QIcon MultiPageWidgetPlugin::icon() const { return {}; } bool MultiPageWidgetPlugin::isInitialized() const { return initialized; }
Eine der Funktionen, die sich unterscheiden, ist die Funktion isContainer(), die in diesem Beispiel true zurückgibt, da unser benutzerdefiniertes Widget als Container verwendet werden soll.
bool MultiPageWidgetPlugin::isContainer() const { return true; }
Eine weitere Funktion, die sich unterscheidet, ist die Funktion, die unser benutzerdefiniertes Widget erstellt:
QWidget *MultiPageWidgetPlugin::createWidget(QWidget *parent) { auto *widget = new MultiPageWidget(parent); connect(widget, &MultiPageWidget::currentIndexChanged, this, &MultiPageWidgetPlugin::currentIndexChanged); connect(widget, &MultiPageWidget::pageTitleChanged, this, &MultiPageWidgetPlugin::pageTitleChanged); return widget; }
Zusätzlich zur Erstellung und Rückgabe des Widgets verbinden wir das currentIndexChanged()-Signal unseres benutzerdefinierten Container-Widgets mit dem currentIndexChanged()-Slot des Plugins, um sicherzustellen, dass der Eigenschaftseditor von Qt Widgets Designer aktualisiert wird, wenn der Benutzer eine andere Seite aufruft. Wir verbinden auch das pageTitleChanged()-Signal des Widgets mit dem pageTitleChanged()-Slot des Plugins.
Der currentIndexChanged()-Slot wird immer dann aufgerufen, wenn das currentIndexChanged() -Signal unseres benutzerdefinierten Widgets ausgegeben wird, d. h. wenn der Benutzer eine andere Seite aufruft:
void MultiPageWidgetPlugin::currentIndexChanged(int index) { Q_UNUSED(index); auto *widget = qobject_cast<MultiPageWidget*>(sender());
Zunächst rufen wir das Objekt, das das Signal sendet, mit den Funktionen QObject::sender() und qobject_cast() ab. Wenn sie in einem durch ein Signal aktivierten Slot aufgerufen wird, gibt QObject::sender() einen Zeiger auf das Objekt zurück, das das Signal gesendet hat; andernfalls gibt sie 0 zurück.
if (widget) { auto *form = QDesignerFormWindowInterface::findFormWindow(widget); if (form) form->emitSelectionChanged(); } }
Sobald wir das Widget haben, können wir den Eigenschaftseditor aktualisieren. Qt Widgets Designer verwendet die Klasse QDesignerPropertySheetExtension, um seinen Eigenschaftseditor zu füttern, und jedes Mal, wenn ein Widget in seinem Arbeitsbereich ausgewählt wird, fragt Qt Widgets Designer nach der Eigenschaftsblatt-Erweiterung des Widgets und aktualisiert den Eigenschaftseditor.
Was wir also erreichen wollen, ist, Qt Widgets Designer zu benachrichtigen, dass sich die interne Auswahl unseres Widgets geändert hat: Zunächst verwenden wir die statische Funktion QDesignerFormWindowInterface::findFormWindow(), um das QDesignerFormWindowInterface Objekt abzufragen, das das Widget enthält. Die Klasse QDesignerFormWindowInterface ermöglicht die Abfrage und Manipulation von Formularfenstern, die im Arbeitsbereich von Qt Widgets Designer erscheinen. Dann müssen wir nur noch ihr emitSelectionChanged()-Signal ausgeben, um eine Aktualisierung des Eigenschaftseditors zu erzwingen.
Beim Ändern eines Seitentitels reicht ein allgemeines Aktualisieren des Eigenschaftseditors nicht aus, da die Eigenschaftserweiterung der Seite aktualisiert werden muss. Aus diesem Grund müssen wir auf das QDesignerPropertySheetExtension Objekt für die Seite zugreifen, deren Titel wir ändern wollen. Die Klasse QDesignerPropertySheetExtension erlaubt es auch, die Eigenschaften eines Widgets zu manipulieren, aber um an die Erweiterung zu gelangen, müssen wir zuerst den Zugriff auf den Erweiterungsmanager von Qt Widgets Designer erhalten:
void MultiPageWidgetPlugin::pageTitleChanged(const QString &title) { Q_UNUSED(title); auto *widget = qobject_cast<MultiPageWidget*>(sender()); if (widget) { auto *page = widget->widget(widget->currentIndex()); auto *form = QDesignerFormWindowInterface::findFormWindow(widget);
Auch hier rufen wir zuerst das Widget ab, das das Signal sendet, indem wir die Funktionen QObject::sender() und qobject_cast() verwenden. Dann rufen wir die aktuelle Seite von dem Widget ab, das das Signal gesendet hat, und wir verwenden die statische Funktion QDesignerFormWindowInterface::findFormWindow(), um das Formular abzurufen, das unser Widget enthält.
auto *editor = form->core(); auto *manager = editor->extensionManager();
Da wir nun das Formularfenster haben, bietet die Klasse QDesignerFormWindowInterface die Funktion core(), die das aktuelle Objekt QDesignerFormEditorInterface zurückgibt. Mit der Klasse QDesignerFormEditorInterface können Sie auf die verschiedenen Komponenten von Qt Designer zugreifen. Insbesondere gibt die Funktion QDesignerFormEditorInterface::extensionManager() einen Verweis auf den aktuellen Erweiterungsmanager zurück.
auto *sheet = qt_extension<QDesignerPropertySheetExtension*>(manager, page); const int propertyIndex = sheet->indexOf(QLatin1String("windowTitle")); sheet->setChanged(propertyIndex, true); } } }
Sobald wir den Erweiterungsmanager haben, können wir das Erweiterungsblatt aktualisieren: Zunächst rufen wir mit der Funktion qt_extension() die Eigenschaftserweiterung für die Seite ab, deren Titel wir ändern wollen. Dann rufen wir den Index für den Seitentitel mit der Funktion QDesignerPropertySheetExtension::indexOf() ab. Wie bereits erwähnt, haben wir uns für die Verwendung der Eigenschaft QWidget::windowTitle entschieden, um den Seitentitel zu speichern (weitere Informationen finden Sie in der Implementierung der Klasse MultiPageWidget in containerextension/multipagewidget.cpp. Schließlich erzwingen wir implizit eine Aktualisierung des Eigenschaftsblatts der Seite, indem wir die Funktion QDesignerPropertySheetExtension::setChanged() aufrufen.
void MultiPageWidgetPlugin::initialize(QDesignerFormEditorInterface *formEditor) { if (initialized) return;
Beachten Sie auch die Funktion initialize(): Die Funktion initialize()
nimmt ein QDesignerFormEditorInterface Objekt als Argument.
auto *manager = formEditor->extensionManager();
Wenn wir Erweiterungen erstellen, die mit benutzerdefinierten Widget-Plugins verbunden sind, müssen wir auf den aktuellen Erweiterungsmanager von Qt Widgets Designer zugreifen, den wir über den Parameter QDesignerFormEditorInterface abrufen.
Die Klasse QExtensionManager ermöglicht es Ihnen nicht nur, die Eigenschaften eines Widgets zu bearbeiten, sondern bietet auch Möglichkeiten zur Verwaltung von Erweiterungen für Qt Widgets Designer. Mit Qt Widgets Designer's current extension manager können Sie die Erweiterung für ein bestimmtes Objekt abrufen. Sie können auch eine Erweiterung für ein bestimmtes Objekt registrieren und deregistrieren. Denken Sie daran, dass eine Erweiterung ein Objekt ist, das das Verhalten von Qt Widgets Designer modifiziert.
Wenn Sie eine Erweiterung registrieren, wird eigentlich die zugehörige Erweiterungsfabrik registriert. In Qt Widgets Designer werden Erweiterungsfabriken verwendet, um benannte Erweiterungen zu suchen und zu erstellen, wenn sie benötigt werden. In diesem Beispiel wird die Container-Erweiterung selbst also erst erstellt, wenn Qt Widgets Designer wissen muss, ob das zugehörige Widget ein Container ist oder nicht.
auto *factory = new MultiPageWidgetExtensionFactory(manager); Q_ASSERT(manager != nullptr); manager->registerExtensions(factory, Q_TYPEID(QDesignerContainerExtension)); initialized = true; }
Wir erstellen ein MultiPageWidgetExtensionFactory
Objekt, das wir mit Qt Widgets Designer's aktuellem extension manager registrieren, das aus dem QDesignerFormEditorInterface Parameter abgerufen wird. Das erste Argument ist die neu erstellte Fabrik und das zweite Argument ist ein Erweiterungsbezeichner, der eine Zeichenkette ist. Das Makro Q_TYPEID()
wandelt die Zeichenkette einfach in eine QLatin1String um.
Die Klasse MultiPageWidgetExtensionFactory
ist eine Unterklasse von QExtensionFactory. Wenn Qt Widgets Designer wissen muss, ob ein Widget ein Container ist oder nicht, durchläuft der Erweiterungsmanager von Qt Widgets Designer alle registrierten Fabriken und ruft die erste auf, die in der Lage ist, eine Container-Erweiterung für dieses Widget zu erstellen. Diese Fabrik wird ihrerseits ein MultiPageWidgetExtension
Objekt erstellen.
QString MultiPageWidgetPlugin::domXml() const { return uR"( <ui language="c++"> <widget class="MultiPageWidget" name="multipagewidget"> <widget class="QWidget" name="page"/> </widget> <customwidgets> <customwidget> <class>MultiPageWidget</class> <extends>QWidget</extends> <addpagemethod>addPage</addpagemethod> </customwidget> </customwidgets> </ui>)"_s; }
Werfen Sie schließlich einen Blick auf die Funktion domXml()
. Diese Funktion enthält Standardeinstellungen für das Widget im Standard-XML-Format, das von Qt Widgets Designer verwendet wird. In diesem Fall geben wir die erste Seite des Containers an; alle anfänglichen Seiten eines mehrseitigen Widgets müssen in dieser Funktion angegeben werden.
MultiPageWidgetExtensionFactory Klassendefinition
Die Klasse MultiPageWidgetExtensionFactory
erbt von QExtensionFactory, die eine Standard-Erweiterungsfabrik für Qt Widgets Designer bereitstellt.
class MultiPageWidgetExtensionFactory: public QExtensionFactory { Q_OBJECT public: explicit MultiPageWidgetExtensionFactory(QExtensionManager *parent = nullptr); protected: QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const override; };
Der Zweck der Unterklasse besteht darin, die Funktion QExtensionFactory::createExtension() neu zu implementieren, so dass sie eine MultiPageWidget
Container-Erweiterung erstellen kann.
Implementierung der MultiPageWidgetExtensionFactory-Klasse
Der Konstruktor der Klasse ruft einfach den Konstruktor der Basisklasse QExtensionFactory auf:
MultiPageWidgetExtensionFactory::MultiPageWidgetExtensionFactory(QExtensionManager *parent) : QExtensionFactory(parent) {}
Wie oben beschrieben, wird die Fabrik aufgerufen, wenn Qt Widgets Designer wissen muss, ob das zugehörige Widget ein Container ist oder nicht.
QObject *MultiPageWidgetExtensionFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const { auto *widget = qobject_cast<MultiPageWidget*>(object); if (widget && (iid == Q_TYPEID(QDesignerContainerExtension))) return new MultiPageWidgetContainerExtension(widget, parent); return nullptr; }
Qt Widgets Der Designer verhält sich gleich, egal ob die angeforderte Erweiterung mit einem Container, einem Member Sheet, einem Property Sheet oder einem Aufgabenmenü verknüpft ist: Der Erweiterungsmanager durchläuft alle registrierten Erweiterungsfabriken, indem er createExtension()
für jede einzelne aufruft, bis er die angeforderte Erweiterung erstellt hat.
Das erste, was wir in MultiPageWidgetExtensionFactory::createExtension()
tun, ist also zu prüfen, ob das QObject, für das die Erweiterung angefordert wird, tatsächlich ein MultiPageWidget
Objekt ist. Dann prüfen wir, ob die angeforderte Erweiterung eine Container-Erweiterung ist.
Wenn das Objekt ein MultiPageWidget ist, das eine Container-Erweiterung anfordert, erstellen wir ein MultiPageWidgetExtension
Objekt und geben es zurück. Andernfalls geben wir einfach einen Null-Zeiger zurück, damit der Erweiterungsmanager von Qt Widgets Designer seine Suche durch die registrierten Factories fortsetzen kann.
MultiPageWidgetContainerExtension Klassendefinition
Die Klasse MultiPageWidgetContainerExtension
erbt von QDesignerContainerExtension und ermöglicht das Hinzufügen (und Löschen) von Seiten zu einem mehrseitigen Container-Plugin in Qt Widgets Designer.
class MultiPageWidgetContainerExtension: public QObject, public QDesignerContainerExtension { Q_OBJECT Q_INTERFACES(QDesignerContainerExtension) public: explicit MultiPageWidgetContainerExtension(MultiPageWidget *widget, QObject *parent); bool canAddWidget() const override; void addWidget(QWidget *widget) override; int count() const override; int currentIndex() const override; void insertWidget(int index, QWidget *widget) override; bool canRemove(int index) const override; void remove(int index) override; void setCurrentIndex(int index) override; QWidget *widget(int index) const override; private: MultiPageWidget *myWidget; };
Es ist wichtig zu erkennen, dass die Klasse QDesignerContainerExtension nur dazu gedacht ist, Qt Widgets Designer Zugriff auf die Funktionalität Ihres benutzerdefinierten mehrseitigen Widgets zu geben; Ihr benutzerdefiniertes mehrseitiges Widget muss die Funktionalität implementieren, die den Funktionen der Erweiterung entspricht.
Beachten Sie auch, dass wir einen Konstruktor implementieren, der zwei Argumente benötigt: das übergeordnete Widget und das MultiPageWidget
Objekt, für das das Aufgabenmenü angefordert wird.
QDesignerContainerExtension stellt standardmäßig einige Menüeinträge im Aufgabenmenü von Qt Widgets Designer zur Verfügung, die es dem Benutzer ermöglichen, dem zugehörigen benutzerdefinierten Mehrseiten-Widget im Arbeitsbereich von Qt Widgets Designer Seiten hinzuzufügen oder zu löschen.
Implementierung der MultiPageWidgetContainerExtension-Klasse
Im Konstruktor speichern wir die Referenz auf das als Parameter übergebene MultiPageWidget
Objekt, d.h. das mit der Erweiterung verbundene Widget. Diese Referenz wird später benötigt, um auf das benutzerdefinierte MultiPage-Widget zuzugreifen, das die gewünschten Aktionen ausführt.
MultiPageWidgetContainerExtension::MultiPageWidgetContainerExtension(MultiPageWidget *widget, QObject *parent) : QObject(parent) , myWidget(widget) { }
Um Qt Widgets Designer vollständig in die Lage zu versetzen, Ihr benutzerdefiniertes mehrseitiges Widget zu verwalten und zu manipulieren, müssen Sie alle Funktionen von QDesignerContainerExtension neu implementieren:
bool MultiPageWidgetContainerExtension::canAddWidget() const { return true; } void MultiPageWidgetContainerExtension::addWidget(QWidget *widget) { myWidget->addPage(widget); } int MultiPageWidgetContainerExtension::count() const { return myWidget->count(); } int MultiPageWidgetContainerExtension::currentIndex() const { return myWidget->currentIndex(); }
Sie müssen canAddWidget() und addWidget() neu implementieren, um eine bestimmte Seite zum Container hinzuzufügen, count() muss die Anzahl der Seiten im Container zurückgeben, und currentIndex() muss den Index der aktuell ausgewählten Seite zurückgeben.
void MultiPageWidgetContainerExtension::insertWidget(int index, QWidget *widget) { myWidget->insertPage(index, widget); } bool MultiPageWidgetContainerExtension::canRemove(int index) const { Q_UNUSED(index); return true; } void MultiPageWidgetContainerExtension::remove(int index) { myWidget->removePage(index); } void MultiPageWidgetContainerExtension::setCurrentIndex(int index) { myWidget->setCurrentIndex(index); } QWidget* MultiPageWidgetContainerExtension::widget(int index) const { return myWidget->widget(index); }
Sie müssen insertWidget() neu implementieren, um dem Container eine bestimmte Seite mit einem bestimmten Index hinzuzufügen, canRemove() und remove(), um die Seite mit einem bestimmten Index zu löschen, setCurrentIndex(), um den Index der aktuell ausgewählten Seite zu setzen, und schließlich widget(), um die Seite mit einem bestimmten Index zurückzugeben.
MultiPageWidget-Klassendefinition
Die Klasse MultiPageWidget ist ein benutzerdefiniertes Container-Widget, das es dem Benutzer ermöglicht, seine Seiten zu bearbeiten und aufzufüllen und zwischen ihnen mithilfe einer Combobox zu navigieren.
class MultiPageWidget : public QWidget { Q_OBJECT Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex) Q_PROPERTY(QString pageTitle READ pageTitle WRITE setPageTitle STORED false) public: explicit MultiPageWidget(QWidget *parent = nullptr); QSize sizeHint() const override; int count() const; int currentIndex() const; QWidget *widget(int index); QString pageTitle() const; public slots: void addPage(QWidget *page); void insertPage(int index, QWidget *page); void removePage(int index); void setPageTitle(const QString &newTitle); void setCurrentIndex(int index); private slots: void pageWindowTitleChanged(); signals: void currentIndexChanged(int index); void pageTitleChanged(const QString &title); private: QStackedWidget *stackWidget; QComboBox *comboBox; };
Das wichtigste Detail ist, dass Ihr benutzerdefiniertes MultiPageWidget eine Funktionalität implementieren muss, die den Memberfunktionen von QDesignerContainerExtension entspricht, da die Klasse QDesignerContainerExtension nur dazu gedacht ist, Qt Designer Zugriff auf die Funktionalität Ihres benutzerdefinierten MultiPageWidgets zu bieten.
Darüber hinaus deklarieren wir die Eigenschaften currentIndex
und pageTitle
und die zugehörigen set- und get-Funktionen. Indem wir diese Attribute als Eigenschaften deklarieren, ermöglichen wir Qt Widgets Designer, sie auf die gleiche Weise zu verwalten, wie die Eigenschaften, die das MultiPageWidget-Widget von QWidget und QObject erbt, z. B. mit dem Eigenschafteneditor.
Beachten Sie das Attribut STORED
in der Deklaration der Eigenschaft pageTitle
: Das Attribut STORED
gibt die Persistenz an, d. h. es erklärt, ob der Wert der Eigenschaft beim Speichern des Objektzustands gespeichert werden muss. Wie bereits erwähnt, haben wir uns für die Speicherung des Seitentitels über die Eigenschaft QWidget::windowTitle entschieden, um jeder Seite einen eigenen Titel geben zu können. Aus diesem Grund ist die Eigenschaft pageTitle
eine "unechte" Eigenschaft, die zu Bearbeitungszwecken bereitgestellt wird und nicht gespeichert werden muss.
Wir müssen auch die Signale currentIndexChanged() und pageTitleChanged() implementieren und ausgeben, um sicherzustellen, dass der Eigenschaftseditor von Qt Widgets Designer aktualisiert wird, wenn der Benutzer eine andere Seite anzeigt oder einen der Seitentitel ändert.
Siehe die Implementierung der MultiPageWidget-Klasse in containerextension/multipagewidget.cpp für weitere Details.
© 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.