Exemple d'extension de conteneur
Création d'un plugin multipages personnalisé pour Qt Widgets Designer.
L'exemple d'extension de conteneur montre comment créer un plugin multipages personnalisé pour Qt Widgets Designer à l'aide de la classe QDesignerContainerExtension.
Qt Widgets Designer montrant l'option permettant d'insérer une page avant la page actuelle dans un objet" src="images/containerextension-example.webp" title="Capture d'écran de l'éditeur d'interface utilisateur Qt Widgets Designer montrant l'option permettant d'insérer une page avant la page actuelle dans un objet"/>
Pour fournir un widget personnalisé pouvant être utilisé avec Qt Widgets Designer, il faut proposer une implémentation autonome. Dans cet exemple, nous utilisons un widget multipages personnalisé conçu pour illustrer la fonctionnalité d’extension de conteneur.
Une extension est un objet qui modifie le comportement d’ Qt Widgets Designer. L’interface QDesignerContainerExtension permet à Qt Widgets Designer de gérer et de manipuler un widget multipages personnalisé, c’est-à-dire d’ajouter et de supprimer des pages dans le widget.
Il existe quatre types d’extensions disponibles dans l’ Qt Widgets Designer :
- QDesignerMemberSheetExtension fournit une extension qui vous permet de manipuler les fonctions membres d’un widget, affichées lors de la configuration des connexions à l’aide du mode d’édition des signaux et des slots de l’éditeur d’ Qt Widgets.
- QDesignerPropertySheetExtension fournit une extension qui vous permet de manipuler les propriétés d’un widget, affichées dans l’éditeur de propriétés d’ Qt Widgets Designer.
- QDesignerTaskMenuExtension fournit une extension qui vous permet d’ajouter des entrées de menu personnalisées au menu des tâches d’ Qt Widgets Designer.
- QDesignerContainerExtension fournit une extension qui vous permet d’ajouter (et de supprimer) des pages à un plugin de conteneur multipages dans Qt Widgets Designer.
Vous pouvez utiliser toutes les extensions en suivant le même modèle que dans cet exemple, en remplaçant simplement la classe de base de l’extension concernée. Pour plus d’informations, consultez Qt Widgets Designer C++ Classes.
L'exemple d’extension « Container » se compose de quatre classes :
MultiPageWidgetest un widget de conteneur personnalisé qui permet à l’utilisateur de manipuler et de remplir ses pages, ainsi que de naviguer entre celles-ci à l’aide d’une liste déroulante.MultiPageWidgetPluginexpose la classe `MultiPageWidget` à l’envi Qt Widgets.MultiPageWidgetExtensionFactorycrée un objet «MultiPageWidgetContainerExtension».MultiPageWidgetContainerExtensionfournit l’extension de conteneur.
Les fichiers de projet des plugins de widgets personnalisés nécessitent des informations supplémentaires pour garantir leur bon fonctionnement dans Qt Widgets Designer. Par exemple, les plugins de widgets personnalisés s’appuient sur des composants fournis avec Qt Widgets Designer, ce qui doit être spécifié dans les fichiers de projet que nous utilisons. Nous allons tout d’abord examiner les fichiers de projet du plugin.
Nous poursuivrons ensuite par l’examen de la classe ` MultiPageWidgetPlugin `, puis nous nous intéresserons aux classes ` MultiPageWidgetExtensionFactory ` et ` MultiPageWidgetContainerExtension `. Enfin, nous jetterons un coup d’œil rapide à la définition de la classe ` MultiPageWidget `.
Fichiers de projet
CMake
Les fichiers de projet doivent indiquer qu’un plugin s’appuyant sur les bibliothèques Qt Widgets Designer doit être compilé :
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
)L'exemple suivant montre comment ajouter les fichiers d'en-tête et les fichiers source du widget :
target_sources(containerextension PRIVATE
multipagewidget.cpp multipagewidget.h
multipagewidgetcontainerextension.cpp multipagewidgetcontainerextension.h
multipagewidgetextensionfactory.cpp multipagewidgetextensionfactory.h
multipagewidgetplugin.cpp multipagewidgetplugin.h
)Nous fournissons une implémentation de l’interface du plugin afin qu’ Qt Widgets Designer puisse utiliser le widget personnalisé. Dans cet exemple particulier, nous fournissons également des implémentations de l’interface d’extension de conteneur et de l’usine d’extensions.
Il est important de s’assurer que le plugin est installé à un emplacement pris en compte par Qt Widgets Designer. Pour ce faire, nous spécifions un chemin cible pour le projet et l’ajoutons à la liste des éléments à installer :
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}"
)L’extension de conteneur est créée sous forme de bibliothèque. Elle sera installée aux côtés des autres plugins d’ Qt Widgets Designer lors de l’installation du projet (à l’aide de ninja install ou d’une procédure d’installation équivalente).
Pour plus d’informations sur les plug-ins, consultez la documentation « Comment créer des plug-ins Qt ».
qmake
L'exemple suivant montre comment lier un plugin aux bibliothèques d'Qt Widgets Designer :
TEMPLATE = lib
CONFIG += plugin
QT += widgets designerL'exemple suivant montre comment ajouter les fichiers d'en-tête et les fichiers source du widget :
HEADERS += multipagewidget.h \
multipagewidgetplugin.h \
multipagewidgetcontainerextension.h \
multipagewidgetextensionfactory.h
SOURCES += multipagewidget.cpp \
multipagewidgetplugin.cpp \
multipagewidgetcontainerextension.cpp \
multipagewidgetextensionfactory.cpp
OTHER_FILES += multipagewidget.jsonL'exemple suivant montre comment installer un plugin dans le chemin d'accès aux plugins de l'Qt Widgets Designer :
target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += targetDéfinition de la classe MultiPageWidgetPlugin
La classe ` MultiPageWidgetPlugin ` expose la classe ` MultiPageWidget ` à l'Qt Widgets Designer. Sa définition est similaire à celle de la classe de plugin de l'exemple « Custom Widget Plugin », qui est expliquée en détail. Les parties de la définition de classe spécifiques à ce widget personnalisé particulier sont le nom de la classe et quelques slots privés :
#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;
};
#endifLa classe de plugin fournit à l’éditeur d’ Qt Widgets s des informations de base sur notre plugin, telles que son nom de classe et son fichier d’inclusion. De plus, elle sait comment créer des instances du widget MultiPageWidget. MultiPageWidgetPlugin définit également la fonction initialize(), qui est appelée une fois le plugin chargé dans l’éditeur d’ Qt Widgets s. Le paramètre QDesignerFormEditorInterface de cette fonction fournit au plugin un accès à l’ensemble des API de l’éditeur d’ Qt Widgets s.
Dans le cas d’un widget multipage tel que le nôtre, nous devons également implémenter deux slots privés, currentIndexChanged() et pageTitleChanged(), afin de pouvoir mettre à jour l’éditeur de propriétés d’ Qt Widgets Designer chaque fois que l’utilisateur consulte une autre page ou modifie l’un des titres de page. Afin de pouvoir attribuer à chaque page son propre titre, nous avons choisi d’utiliser la propriété ` QWidget::windowTitle ` pour stocker le titre de la page (pour plus d’informations, voir l’implémentation de la classe `MultiPageWidget` dans `containerextension/multipagewidget.cpp`). Notez qu’il n’existe actuellement aucun moyen d’ajouter une propriété personnalisée (par exemple, un titre de page) aux pages sans utiliser une propriété prédéfinie comme espace réservé.
La classe ` MultiPageWidgetPlugin ` hérite à la fois de ` QObject ` et de ` QDesignerCustomWidgetInterface`. Il est important de se rappeler, lors de l’utilisation de l’héritage multiple, de s’assurer que toutes les interfaces (c’est-à-dire les classes qui n’héritent pas de ` Q_OBJECT`) sont signalées au système de méta-objets à l’aide de la macro ` Q_INTERFACES()`. Cela permet à Qt Widgets Designer d’utiliser ` qobject_cast()` pour interroger les interfaces prises en charge en utilisant uniquement un pointeur ` QObject `.
Pour s’assurer que Qt reconnaisse le widget comme un plugin, exportez les informations pertinentes concernant le widget en ajoutant la macro Q_PLUGIN_METADATA():
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidget")Qt Widgets Grâce à cette macro, le Designer d'Qt Widgets s peut accéder au widget personnalisé et le créer. Sans cette macro, le Designer d' s ne peut en aucun cas utiliser le widget.
Implémentation de la classe MultiPageWidgetPlugin
L’implémentation de la classe `MultiPageWidgetPlugin` est en grande partie équivalente à celle de la classe de plugin de l’exemple de plugin de widget personnalisé:
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;
}L'une des fonctions qui diffère est la fonction isContainer(), qui renvoie « true » dans cet exemple, car notre widget personnalisé est destiné à être utilisé comme conteneur.
bool MultiPageWidgetPlugin::isContainer() const
{
return true;
}Une autre fonction qui diffère est celle qui crée notre widget personnalisé :
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;
}En plus de créer et de renvoyer le widget, nous connectons le signal `currentIndexChanged()` de notre widget conteneur personnalisé au slot `currentIndexChanged()` du plugin afin de garantir que l’éditeur de propriétés d’ Qt Widgets Designer soit mis à jour chaque fois que l’utilisateur consulte une autre page. Nous connectons également le signal `pageTitleChanged()` du widget au slot `pageTitleChanged()` du plugin.
Le slot `currentIndexChanged()` est appelé chaque fois que le signal `currentIndexChanged()` de notre widget personnalisé est émis, c'est-à-dire chaque fois que l'utilisateur consulte une autre page :
void MultiPageWidgetPlugin::currentIndexChanged(int index)
{
Q_UNUSED(index);
auto *widget = qobject_cast<MultiPageWidget*>(sender());Tout d’abord, nous récupérons l’objet émettant le signal à l’aide des fonctions ` QObject::sender()` et ` qobject_cast()`. S’il est appelé dans un slot activé par un signal, ` QObject::sender()` renvoie un pointeur vers l’objet qui a envoyé le signal ; sinon, il renvoie 0.
if (widget) {
auto *form = QDesignerFormWindowInterface::findFormWindow(widget);
if (form)
form->emitSelectionChanged();
}
}Une fois que nous avons le widget, nous pouvons mettre à jour l’éditeur de propriétés. Qt Widgets Designer utilise la classe QDesignerPropertySheetExtension pour alimenter son éditeur de propriétés, et chaque fois qu’un widget est sélectionné dans son espace de travail, Qt Widgets Designer interroge l’extension de la feuille de propriétés du widget et met à jour l’éditeur de propriétés.
Notre objectif est donc d’informer Qt Widgets Designer que la sélection interne de notre widget a changé : nous utilisons d’abord la fonction statique QDesignerFormWindowInterface::findFormWindow() pour récupérer l’objet QDesignerFormWindowInterface contenant le widget. La classe QDesignerFormWindowInterface vous permet d’interroger et de manipuler les fenêtres de formulaire apparaissant dans l’espace de travail d’ Qt Widgets Designer. Ensuite, il suffit d’émettre son signal ` emitSelectionChanged()` pour forcer la mise à jour de l’éditeur de propriétés.
Lorsqu’on modifie le titre d’une page, un rafraîchissement générique de l’éditeur de propriétés ne suffit pas, car c’est en réalité l’extension de propriétés de la page qui doit être mise à jour. C’est pourquoi nous devons accéder à l’objet ` QDesignerPropertySheetExtension ` correspondant à la page dont nous souhaitons modifier le titre. La classe ` QDesignerPropertySheetExtension ` permet également de manipuler les propriétés d’un widget, mais pour obtenir l’extension, nous devons d’abord accéder au gestionnaire d’extensions d’ Qt Widgets Designer :
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);Une fois encore, nous récupérons d’abord le widget émettant le signal, à l’aide des fonctions ` QObject::sender()` et ` qobject_cast()`. Ensuite, nous récupérons la page actuelle à partir du widget qui a émis le signal, puis nous utilisons la fonction statique ` QDesignerFormWindowInterface::findFormWindow()` pour récupérer le formulaire contenant notre widget.
auto *editor = form->core();
auto *manager = editor->extensionManager();Maintenant que nous disposons de la fenêtre du formulaire, la classe ` QDesignerFormWindowInterface ` fournit la fonction ` core()` qui renvoie l’objet ` QDesignerFormEditorInterface ` actuel. La classe ` QDesignerFormEditorInterface ` vous permet d’accéder aux différents composants de ` Qt Designer`. En particulier, la fonction ` QDesignerFormEditorInterface::extensionManager()` renvoie une référence au gestionnaire d’extensions actuel.
auto *sheet = qt_extension<QDesignerPropertySheetExtension*>(manager, page);
const int propertyIndex = sheet->indexOf(QLatin1String("windowTitle"));
sheet->setChanged(propertyIndex, true);
}
}
}Une fois que nous disposons du gestionnaire d’extensions, nous pouvons mettre à jour la feuille d’extension : nous récupérons d’abord la propriété extension de la page dont nous souhaitons modifier le titre, à l’aide de la fonction qt_extension(). Ensuite, nous récupérons l’index du titre de la page à l’aide de la fonction QDesignerPropertySheetExtension::indexOf(). Comme mentionné précédemment, nous avons choisi d’utiliser la propriété ` QWidget::windowTitle ` pour stocker le titre de la page (pour plus d’informations, voir l’implémentation de la classe `MultiPageWidget` dans `containerextension/multipagewidget.cpp`). Enfin, nous forçons implicitement une mise à jour de la feuille de propriétés de la page en appelant la fonction ` QDesignerPropertySheetExtension::setChanged()`.
void MultiPageWidgetPlugin::initialize(QDesignerFormEditorInterface *formEditor)
{
if (initialized)
return;Notez également la fonction `initialize()` : la fonction ` initialize() ` prend un objet ` QDesignerFormEditorInterface ` en argument.
auto *manager = formEditor->extensionManager();Lors de la création d’extensions associées à des plugins de widgets personnalisés, nous devons accéder au gestionnaire d’extensions actuel d’ Qt Widgets Designer, que nous récupérons à partir du paramètre QDesignerFormEditorInterface.
En plus de vous permettre de manipuler les propriétés d’un widget, la classe ` QExtensionManager ` fournit des fonctionnalités de gestion des extensions pour ` Qt Widgets Designer`. À l’aide du gestionnaire d’extensions actuel d’` Qt Widgets Designer`, vous pouvez récupérer l’extension d’un objet donné. Vous pouvez également enregistrer et désenregistrer une extension pour un objet donné. N’oubliez pas qu’une extension est un objet qui modifie le comportement d’` Qt Widgets Designer`.
Lors de l’enregistrement d’une extension, c’est en réalité l’usine d’extensions associée qui est enregistrée. Dans Qt Widgets Designer, les usines d’extensions sont utilisées pour rechercher et créer des extensions nommées à la demande. Ainsi, dans cet exemple, l’extension « container » elle-même n’est pas créée tant que Qt Widgets Designer n’a pas besoin de savoir si le widget associé est un conteneur ou non.
auto *factory = new MultiPageWidgetExtensionFactory(manager);
Q_ASSERT(manager != nullptr);
manager->registerExtensions(factory, Q_TYPEID(QDesignerContainerExtension));
initialized = true;
}Nous créons un objet ` MultiPageWidgetExtensionFactory ` que nous enregistrons à l’aide de l’ extension manager e actuelle du Designer d’ Qt Widgets, récupérée via le paramètre ` QDesignerFormEditorInterface `. Le premier argument est la fabrique nouvellement créée et le deuxième argument est un identifiant d’extension, qui est une chaîne de caractères. La macro ` Q_TYPEID() ` convertit simplement cette chaîne en un ` QLatin1String`.
La classe ` MultiPageWidgetExtensionFactory ` est une sous-classe de ` QExtensionFactory`. Lorsque ` Qt Widgets Designer` doit déterminer si un widget est un conteneur ou non, le gestionnaire d’extensions de ` Qt Widgets Designer` parcourt toutes ses fabriques enregistrées et invoque la première capable de créer une extension de conteneur pour ce widget. Cette fabrique créera à son tour un objet ` MultiPageWidgetExtension `.
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;
}Enfin, examinez la fonction ` domXml() `. Cette fonction inclut les paramètres par défaut du widget au format XML standard utilisé par Qt Widgets Designer. Dans ce cas, nous spécifions la première page du conteneur ; toutes les pages initiales d'un widget multipages doivent être spécifiées au sein de cette fonction.
Définition de la classe MultiPageWidgetExtensionFactory
La classe ` MultiPageWidgetExtensionFactory ` hérite de ` QExtensionFactory `, qui fournit une fabrique d’extensions standard pour Qt Widgets Designer.
class MultiPageWidgetExtensionFactory: public QExtensionFactory
{
Q_OBJECT
public:
explicit MultiPageWidgetExtensionFactory(QExtensionManager *parent = nullptr);
protected:
QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const override;
};Le but de la sous-classe est de réimplémenter la fonction ` QExtensionFactory::createExtension()`, afin de lui permettre de créer une extension de conteneur ` MultiPageWidget `.
Implémentation de la classe MultiPageWidgetExtensionFactory
Le constructeur de la classe appelle simplement le constructeur de la classe de base ` QExtensionFactory ` :
MultiPageWidgetExtensionFactory::MultiPageWidgetExtensionFactory(QExtensionManager *parent)
: QExtensionFactory(parent)
{}Comme décrit ci-dessus, la fabrique est invoquée lorsque Qt Widgets Designer doit déterminer si le widget associé est un conteneur ou non.
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 Le comportement de Designer est le même, que l’extension demandée soit associée à un conteneur, à une feuille de membres, à une feuille de propriétés ou à un menu de tâches : son gestionnaire d’extensions parcourt toutes ses fabriques d’extensions enregistrées en appelant createExtension() pour chacune d’entre elles, jusqu’à ce que l’une d’elles réponde en créant l’extension demandée.
La première chose que nous faisons dans ` MultiPageWidgetExtensionFactory::createExtension() `, c’est donc de vérifier si l’ QObject, pour lequel l’extension est demandée, est bien un objet ` MultiPageWidget `. Ensuite, nous vérifions si l’extension demandée est une extension de conteneur.
Si l’objet est un MultiPageWidget demandant une extension de conteneur, nous créons et renvoyons un objet ` MultiPageWidgetExtension `. Sinon, nous renvoyons simplement un pointeur null, ce qui permet au gestionnaire d’extensions d’ Qt Widgets Designer de poursuivre sa recherche parmi les fabriques enregistrées.
Définition de la classe MultiPageWidgetContainerExtension
La classe ` MultiPageWidgetContainerExtension ` hérite de ` QDesignerContainerExtension `, ce qui vous permet d’ajouter (et de supprimer) des pages à un plugin de conteneur multipages dans le Designer d’ Qt Widgets.
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;
};Il est important de noter que la classe ` QDesignerContainerExtension ` a pour seul but de permettre à l'Qt Widgets Designer d'accéder aux fonctionnalités de votre widget multipage personnalisé ; ce dernier doit implémenter les fonctionnalités correspondant aux fonctions de l'extension.
Notez également que nous implémentons un constructeur qui prend deux arguments : le widget parent et l’objet ` MultiPageWidget ` pour lequel le menu de tâches est demandé.
QDesignerContainerExtension fournit par défaut plusieurs entrées de menu dans le menu des tâches d’ Qt Widgets Designer, permettant à l’utilisateur d’ajouter ou de supprimer des pages au widget multipages personnalisé associé dans l’espace de travail d’ Qt Widgets Designer.
Implémentation de la classe MultiPageWidgetContainerExtension
Dans le constructeur, nous enregistrons la référence à l’objet ` MultiPageWidget ` transmis en paramètre, c’est-à-dire le widget associé à l’extension. Nous en aurons besoin ultérieurement pour accéder au widget multipages personnalisé et effectuer les actions demandées.
MultiPageWidgetContainerExtension::MultiPageWidgetContainerExtension(MultiPageWidget *widget,
QObject *parent)
: QObject(parent)
, myWidget(widget)
{
}Pour permettre à Qt Widgets Designer de gérer et de manipuler pleinement votre widget multipages personnalisé, vous devez réimplémenter toutes les fonctions de QDesignerContainerExtension:
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();
}Vous devez réimplémenter ` canAddWidget()` et ` addWidget()` pour ajouter une page donnée au conteneur, ` count()` pour renvoyer le nombre de pages dans le conteneur, et ` currentIndex()` pour renvoyer l’index de la page actuellement sélectionnée.
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);
}Vous devez réimplémenter les méthodes insertWidget() pour ajouter une page donnée au conteneur à un index donné, canRemove() et remove() pour supprimer la page à un index donné, setCurrentIndex() pour définir l'index de la page actuellement sélectionnée, et enfin widget() pour renvoyer la page à un index donné.
Définition de la classe MultiPageWidget
La classe MultiPageWidget est un widget conteneur personnalisé qui permet à l’utilisateur de manipuler et de remplir ses pages, puis de naviguer entre celles-ci à l’aide d’une liste déroulante.
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;
};Le point essentiel à retenir est que votre widget multipages personnalisé doit implémenter des fonctionnalités correspondant aux fonctions membres de la classe ` QDesignerContainerExtension`, car la classe ` QDesignerContainerExtension ` est uniquement destinée à fournir un accès de type « Qt Designer » aux fonctionnalités de votre widget multipages personnalisé.
De plus, nous déclarons les propriétés ` currentIndex ` et ` pageTitle `, ainsi que leurs fonctions `set` et `get` associées. En déclarant ces attributs en tant que propriétés, nous permettons à Qt Widgets Designer de les gérer de la même manière qu’il gère les propriétés dont le widget `MultiPageWidget` hérite de ` QWidget ` et ` QObject`, notamment via l’éditeur de propriétés.
Notez l’attribut ` STORED ` dans la déclaration de la propriété ` pageTitle ` : l’attribut ` STORED ` indique la persistance, c’est-à-dire qu’il précise si la valeur de la propriété doit être conservée lors de la sauvegarde de l’état d’un objet. Comme mentionné ci-dessus, nous avons choisi de stocker le titre de la page à l’aide de la propriété QWidget::windowTitle afin de pouvoir attribuer à chaque page son propre titre. C’est pourquoi la propriété pageTitle est une « fausse » propriété, fournie à des fins d’édition, et qui n’a pas besoin d’être stockée.
Nous devons également implémenter et émettre les signaux `currentIndexChanged()` et `pageTitleChanged()` afin de garantir que l’éditeur de propriétés d’ Qt Widgets Designer soit mis à jour chaque fois que l’utilisateur consulte une autre page ou modifie l’un des titres de page.
Consultez l’implémentation de la classe MultiPageWidget dans containerextension/multipagewidget.cpp pour plus de détails.
© 2026 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.