Sur cette page

Extension du menu des tâches

Création d'un plugin widget personnalisé pour Qt Widgets Designer et fourniture d'entrées de menu de tâches personnalisées associées au plugin.

L'exemple d'extension de menu de tâches montre comment créer un plugin de widget personnalisé pour Qt Widgets Designeret comment utiliser la classe QDesignerTaskMenuExtension pour fournir des entrées de menu de tâches personnalisées associées au plugin.

Capture d'écran d'une action personnalisée "Edit State..." dans un menu contextuel de <span translate=Qt Widgets Designer." src="images/taskmenuextension-example.webp" title="Capture d'écran d'une action personnalisée "Edit State..." dans un menu contextuel de Qt Widgets Designer."/>

Pour fournir un widget personnalisé pouvant être utilisé avec Qt Widgets Designer, nous devons fournir une implémentation autonome. Dans cet exemple, nous utilisons un widget personnalisé conçu pour montrer la fonction d'extension du menu des tâches : Le widget TicTacToe.

Une extension est un objet qui modifie le comportement de Qt Widgets Designer. QDesignerTaskMenuExtension peut fournir des entrées de menu de tâches personnalisées lorsqu'un widget doté de cette extension est sélectionné.

Il existe quatre types d'extensions disponibles dans Qt Widgets Designer:

  • QDesignerContainerExtension fournit une extension qui vous permet d'ajouter (et de supprimer) des pages à un plugin de conteneur multipage dans Qt Widgets Designer.
  • QDesignerMemberSheetExtension fournit une extension qui vous permet de manipuler les fonctions membres d'un widget qui s'affichent lors de la configuration des connexions à l'aide du mode d'édition des signaux et des emplacements de Qt Widgets Designer.
  • QDesignerPropertySheetExtension fournit une extension qui vous permet de manipuler les propriétés d'un widget, affichée dans l'éditeur de propriétés de Qt Widgets Designer.
  • QDesignerTaskMenuExtension fournit une extension qui vous permet d'ajouter des entrées de menu personnalisées au menu des tâches de Qt Widgets Designer.

Vous pouvez utiliser toutes les extensions en suivant le même schéma que dans cet exemple, en remplaçant uniquement la classe de base de l'extension concernée. Pour plus d'informations, consultez la page Qt Widgets Designer C++ Classes.

L'exemple d'extension du menu des tâches se compose de cinq classes :

  • TicTacToe est un widget personnalisé qui permet à l'utilisateur de jouer au jeu du Tic-Tac-Toe.
  • TicTacToePlugin expose la classe TicTacToe à Qt Widgets Designer.
  • TicTacToeTaskMenuFactory crée un objet TicTacToeTaskMenu.
  • TicTacToeTaskMenu fournit l'extension du menu des tâches, c'est-à-dire les entrées du menu des tâches associées au plugin.
  • TicTacToeDialog permet à l'utilisateur de modifier l'état d'un plugin Tic-Tac-Toe chargé dans Qt Widgets Designer.

Le fichier de projet pour les plugins de widgets personnalisés nécessite quelques informations supplémentaires pour garantir qu'ils fonctionneront 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 le fichier de projet que nous utilisons. Nous allons d'abord examiner le fichier de projet du plugin.

Ensuite, nous examinerons la classe TicTacToePlugin, puis les classes TicTacToeTaskMenuFactory et TicTacToeTaskMenu. Enfin, nous examinerons la classe TicTacToeDialog avant de jeter un coup d'œil rapide à la définition de la classe du widget TicTacToe.

Fichiers du projet

CMake

Les fichiers de projet doivent indiquer qu'un plugin liant les bibliothèques Qt Widgets Designer doit être construit :

find_package(Qt6 REQUIRED COMPONENTS Core Designer Gui Widgets)

qt_add_plugin(taskmenuextension)

target_link_libraries(taskmenuextension PUBLIC
    Qt::Core
    Qt::Designer
    Qt::Gui
    Qt::Widgets
)

L'exemple suivant montre comment ajouter les fichiers d'en-tête et de source du widget :

target_sources(taskmenuextension PRIVATE
    tictactoe.cpp tictactoe.h
    tictactoedialog.cpp tictactoedialog.h
    tictactoeplugin.cpp tictactoeplugin.h
    tictactoetaskmenu.cpp tictactoetaskmenu.h
)

Nous fournissons une implémentation de l'interface du plugin afin que Qt Widgets Designer puisse utiliser le widget personnalisé. Dans cet exemple particulier, nous fournissons également des implémentations de l'extension du menu des tâches et de la fabrique d'extensions, ainsi qu'une implémentation du dialogue.

Il est important de s'assurer que le plugin est installé à un emplacement qui peut être recherché 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 taskmenuextension
    RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
    BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
    LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

L'extension du menu des tâches est créée en tant que bibliothèque. Elle sera installée avec les autres plugins de 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 plugins, voir la documentation How to Create Qt Plugins (Comment créer des plugins Qt ).

qmake

L'exemple suivant montre comment lier un plugin aux bibliothèques Qt Widgets Designer:

TEMPLATE = lib
CONFIG  += plugin

QT      += widgets designer

L'exemple suivant montre comment ajouter les fichiers d'en-tête et de source du widget :

HEADERS += tictactoe.h \
           tictactoedialog.h \
           tictactoeplugin.h \
           tictactoetaskmenu.h
SOURCES += tictactoe.cpp \
           tictactoedialog.cpp \
           tictactoeplugin.cpp \
           tictactoetaskmenu.cpp
OTHER_FILES += tictactoe.json

L'exemple suivant montre comment installer un plugin dans le chemin des plugins de Qt Widgets Designer:

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

Définition de la classe TicTacToePlugin

La classe TicTacToePlugin expose la classe the TicTacToe à Qt Widgets Designer. Sa définition est équivalente à la classe de plugin de l'exemple Custom Widget Plugin, qui est expliquée en détail. La seule partie de la définition de la classe qui est spécifique à ce widget personnalisé particulier est le nom de la classe.

Pour s'assurer que Qt Widgets reconnaisse le widget en tant que plugin, exportez les informations pertinentes sur le widget en ajoutant la macro Q_PLUGIN_METADATA():

#ifndef TICTACTOEPLUGIN_H
#define TICTACTOEPLUGIN_H

#include <QtUiPlugin/QDesignerCustomWidgetInterface>

class QIcon;
class QWidget;

class TicTacToePlugin : public QObject, public QDesignerCustomWidgetInterface
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")
    Q_INTERFACES(QDesignerCustomWidgetInterface)

public:
    explicit TicTacToePlugin(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:
    bool initialized = false;
};

#endif

La classe de plugin fournit à Qt Widgets Designer des informations de base sur notre plugin, telles que son nom de classe et son fichier d'inclusion. En outre, elle sait comment créer des instances du widget TicTacToe. TicTacToePlugin définit également la fonction initialize() qui est appelée après le chargement du plugin dans Qt Widgets Designer. Le paramètre QDesignerFormEditorInterface de la fonction fournit au plugin une passerelle vers toutes les API de Qt Widgets Designer.

La classe TicTacToePlugin hérite à la fois de QObject et de QDesignerCustomWidgetInterface. Il est important de se rappeler, lors de l'utilisation de l'héritage multiple, que toutes les interfaces (c'est-à-dire les classes qui n'héritent pas de Q_OBJECT) sont portées à la connaissance du système de métaobjets à l'aide de la macro Q_INTERFACES(). Cela permet à Qt Widgets Designer d'utiliser qobject_cast() pour rechercher les interfaces prises en charge en n'utilisant rien d'autre qu'un pointeur QObject.

Mise en œuvre de la classe TicTacToePlugin

L'implémentation de la classe TicTacToePlugin est en grande partie équivalente à la classe de plugin de l'exemple Custom Widget Plugin:

TicTacToePlugin::TicTacToePlugin(QObject *parent)
    : QObject(parent)
{
}

QString TicTacToePlugin::name() const
{
    return u"TicTacToe"_s;
}

QString TicTacToePlugin::group() const
{
    return u"Display Widgets [Examples]"_s;
}

QString TicTacToePlugin::toolTip() const
{
    return u"Tic Tac Toe Example, demonstrating class QDesignerTaskMenuExtension (C++)"_s;
}

QString TicTacToePlugin::whatsThis() const
{
    return {};
}

QString TicTacToePlugin::includeFile() const
{
    return u"tictactoe.h"_s;
}

QIcon TicTacToePlugin::icon() const
{
    return {};
}

bool TicTacToePlugin::isContainer() const
{
    return false;
}

QWidget *TicTacToePlugin::createWidget(QWidget *parent)
{
    auto *ticTacToe = new TicTacToe(parent);
    ticTacToe->setState(u"-X-XO----"_s);
    return ticTacToe;
}

bool TicTacToePlugin::isInitialized() const
{
    return initialized;
}

La seule fonction qui diffère de manière significative est la fonction initialize() :

void TicTacToePlugin::initialize(QDesignerFormEditorInterface *formEditor)
{

La fonction initialize() prend un objet QDesignerFormEditorInterface comme argument. La classe QDesignerFormEditorInterface permet d'accéder aux composants de Qt Widgets Designer.

Dans Qt Widgets Designer, vous pouvez créer deux types de plugins : les plugins de widgets personnalisés et les plugins d'outils. QDesignerFormEditorInterface donne accès à tous les composants Qt Widgets Designer dont vous avez normalement besoin pour créer un plugin d'outils : le gestionnaire d'extension, l'inspecteur d'objets, l'éditeur de propriétés et la boîte à widgets. Les plugins de widgets personnalisés ont accès aux mêmes composants.

    if (initialized)
        return;

    auto *manager = formEditor->extensionManager();
    Q_ASSERT(manager != nullptr);

Lors de la création d'extensions associées à des plugins de widgets personnalisés, nous devons accéder au gestionnaire d'extensions actuel de Qt Widgets Designer, que nous récupérons à partir du paramètre QDesignerFormEditorInterface.

Qt Widgets DesignerLa page QDesignerFormEditorInterface contient des informations sur tous les composants de Qt Designer: L'éditeur d'actions, l'inspecteur d'objets, l'éditeur de propriétés, la boîte à outils et les gestionnaires de fenêtres d'extension et de formulaire.

La classe QExtensionManager fournit des fonctions de gestion des extensions pour Qt Widgets Designer. En utilisant le gestionnaire d'extension actuel de 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é. Rappelez-vous qu'une extension est un objet qui modifie le comportement de Qt Widgets Designer.

Lors de l'enregistrement d'une extension, c'est en fait la fabrique d'extensions associée qui est enregistrée. Dans Qt Widgets Designer, les fabriques d'extensions sont utilisées pour rechercher et créer des extensions nommées au fur et à mesure des besoins. Ainsi, dans cet exemple, l'extension du menu des tâches n'est pas créée tant qu'un menu des tâches n'est pas demandé par l'utilisateur.

    manager->registerExtensions(new TicTacToeTaskMenuFactory(manager),
                                Q_TYPEID(QDesignerTaskMenuExtension));

    initialized = true;
}

QString TicTacToePlugin::domXml() const
{
    return uR"(
<ui language="c++">
    <widget class="TicTacToe" name="ticTacToe"/>
    <customwidgets>
        <customwidget>
            <class>TicTacToe</class>
            <propertyspecifications>
            <tooltip name="state">Tic Tac Toe state</tooltip>
            <stringpropertyspecification name="state" notr="true" type="singleline"/>
            </propertyspecifications>
        </customwidget>
    </customwidgets>
</ui>
)"_s;
}

Nous créons un objet TicTacToeTaskMenuFactory que nous enregistrons à l'aide de Qt Widgets Designer's current extension manager récupéré à partir du paramètre QDesignerFormEditorInterface. Le premier argument est la fabrique nouvellement créée et le second est un identifiant d'extension qui est une chaîne de caractères. La macro Q_TYPEID() convertit simplement la chaîne en QLatin1String.

La classe TicTacToeTaskMenuFactory est une sous-classe de QExtensionFactory. Lorsque l'utilisateur demande un menu de tâches en cliquant avec le bouton droit de la souris sur un widget doté de l'extension de menu de tâches spécifiée, le gestionnaire d'extensions de Qt Widgets Designer passe en revue toutes les fabriques enregistrées et invoque la première qui est en mesure de créer une extension de menu de tâches pour le widget sélectionné. Cette usine créera à son tour un objet TicTacToeTaskMenu (l'extension).

Nous omettons de réimplémenter la fonction QDesignerCustomWidgetInterface::domXml() (qui inclut les paramètres par défaut du widget dans le format XML standard utilisé par Qt Widgets Designer), étant donné qu'aucune valeur par défaut n'est nécessaire.

    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")

Enfin, nous utilisons la macro Q_PLUGIN_METADATA() pour exporter la classe TicTacToePlugin afin de l'utiliser avec les classes de gestion des plugins de Qt : Cette macro garantit que Qt Widgets Designer peut accéder au widget personnalisé et le construire. Sans cette macro, Qt Widgets Designer n'a aucun moyen d'utiliser le widget.

Définition de la classe TicTacToeTaskMenuFactory

La classe TicTacToeTaskMenuFactory hérite de QExtensionFactory qui fournit une usine d'extension standard pour Qt Widgets Designer.

class TicTacToeTaskMenuFactory : public QExtensionFactory
{
    Q_OBJECT

public:
    explicit TicTacToeTaskMenuFactory(QExtensionManager *parent = nullptr);

protected:
    QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const override;
};

L'objectif de la sous-classe est de réimplémenter la fonction QExtensionFactory::createExtension(), ce qui lui permet de créer une extension de menu de tâches TicTacToe.

Mise en œuvre de la classe TicTacToeTaskMenuFactory

Le constructeur de la classe appelle simplement le constructeur de la classe de base QExtensionFactory:

TicTacToeTaskMenuFactory::TicTacToeTaskMenuFactory(QExtensionManager *parent)
    : QExtensionFactory(parent)
{
}

Comme décrit ci-dessus, la fabrique est invoquée lorsque l'utilisateur demande un menu de tâches en cliquant avec le bouton droit de la souris sur un widget avec l'extension de menu de tâches spécifiée dans Qt Widgets Designer.

Qt Widgets DesignerLe comportement de la fabrique est le même, que l'extension demandée soit associée à un conteneur, à une feuille de membre, à une feuille de propriété ou à un menu de tâches : Son gestionnaire d'extensions parcourt toutes les usines d'extensions enregistrées en appelant createExtension() pour chacune d'entre elles jusqu'à ce que l'une d'entre elles réponde en créant l'extension demandée.

QObject *TicTacToeTaskMenuFactory::createExtension(QObject *object,
                                                   const QString &iid,
                                                   QObject *parent) const
{
    if (iid != Q_TYPEID(QDesignerTaskMenuExtension))
        return nullptr;

    if (auto *tic = qobject_cast<TicTacToe*>(object))
        return new TicTacToeTaskMenu(tic, parent);

    return nullptr;
}

La première chose que nous faisons dans TicTacToeTaskMenuFactory::createExtension() est donc de vérifier si l'extension demandée est une extension de menu de tâches. Si c'est le cas et que le widget qui la demande est un widget TicTacToe, nous créons et renvoyons un objet TicTacToeTaskMenu. Dans le cas contraire, nous renvoyons simplement un pointeur nul, ce qui permet au gestionnaire d'extensions de Qt Widgets Designer de poursuivre sa recherche parmi les usines enregistrées.

Définition de la classe TicTacToeTaskMenu

Capture d'écran montrant toutes les options permettant de modifier un widget dans l'éditeur d'interface utilisateur

La classe TicTacToeTaskMenu hérite de QDesignerTaskMenuExtension qui vous permet d'ajouter des entrées personnalisées (sous la forme d'actions Q) au menu des tâches dans Qt Widgets Designer.

class TicTacToeTaskMenu : public QObject, public QDesignerTaskMenuExtension
{
    Q_OBJECT
    Q_INTERFACES(QDesignerTaskMenuExtension)

public:
    explicit TicTacToeTaskMenu(TicTacToe *tic, QObject *parent);

    QAction *preferredEditAction() const override;
    QList<QAction *> taskActions() const override;

private slots:
    void editState();

private:
    QAction *editStateAction;
    TicTacToe *ticTacToe;
};

Nous réimplémentons les fonctions preferredEditAction() et taskActions(). Notez que nous implémentons un constructeur qui prend deux arguments : le widget parent et le widget TicTacToe pour lequel le menu des tâches est demandé.

En outre, nous déclarons l'emplacement privé editState(), notre editStateAction personnalisé et un pointeur privé vers le widget TicTacToe dont nous voulons modifier l'état.

Mise en œuvre de la classe TicTacToeTaskMenu

TicTacToeTaskMenu::TicTacToeTaskMenu(TicTacToe *tic, QObject *parent)
    : QObject(parent)
    , editStateAction(new QAction(tr("Edit State..."), this))
    , ticTacToe(tic)
{
    connect(editStateAction, &QAction::triggered, this, &TicTacToeTaskMenu::editState);
}

Dans le constructeur, nous enregistrons d'abord la référence au widget TicTacToe envoyé en paramètre, c'est-à-dire le widget dont nous voulons modifier l'état. Nous en aurons besoin plus tard lorsque notre action personnalisée sera invoquée. Nous créons également notre editStateAction personnalisé et le connectons au slot editState().

void TicTacToeTaskMenu::editState()
{
    TicTacToeDialog dialog(ticTacToe);
    dialog.exec();
}

Le slot editState() est appelé chaque fois que l'utilisateur choisit l'option Edit State... dans le menu des tâches d'un widget TicTacToe. Le slot crée un TicTacToeDialog qui présente l'état actuel du widget et permet à l'utilisateur de modifier son état en jouant au jeu.

QAction *TicTacToeTaskMenu::preferredEditAction() const
{
    return editStateAction;
}

Nous réimplémentons la fonction preferredEditAction() pour qu'elle renvoie notre editStateAction personnalisé en tant qu'action qui doit être invoquée lorsque l'on sélectionne un widget TicTacToe et que l'on appuie sur F2.

QList<QAction *> TicTacToeTaskMenu::taskActions() const
{
    return QList<QAction *>{editStateAction};
}

Nous réimplémentons la fonction taskActions() pour renvoyer une liste de nos actions personnalisées et les faire apparaître au-dessus des entrées de menu par défaut dans le menu des tâches d'un widget TicTacToe.

Définition de la classe TicTacToeDialog

Capture d'écran montrant le mode d'édition d'un widget

La classe TicTacToeDialog hérite de QDialog. Le dialogue permet à l'utilisateur de modifier l'état du plugin Tic-Tac-Toe actuellement sélectionné.

class TicTacToeDialog : public QDialog
{
    Q_OBJECT

public:
    explicit TicTacToeDialog(TicTacToe *plugin = nullptr, QWidget *parent = nullptr);

    QSize sizeHint() const override;

private slots:
    void resetState();
    void saveState();

private:
    TicTacToe *editor;
    TicTacToe *ticTacToe;
    QDialogButtonBox *buttonBox;
};

Nous réimplémentons la fonction sizeHint(). Nous déclarons également deux emplacements privés : resetState() et saveState(). En plus des boutons et des dispositions de la boîte de dialogue, nous déclarons deux pointeurs TicTacToe, l'un vers le widget avec lequel l'utilisateur peut interagir et l'autre vers le plugin de widget personnalisé original dont l'état doit être modifié par l'utilisateur.

Mise en œuvre de la classe TicTacToeDialog

TicTacToeDialog::TicTacToeDialog(TicTacToe *tic, QWidget *parent)
    : QDialog(parent)
    , editor(new TicTacToe)
    , ticTacToe(tic)
    , buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok
                                     | QDialogButtonBox::Cancel
                                     | QDialogButtonBox::Reset))
{
    editor->setState(ticTacToe->state());

    connect(buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked,
            this, &TicTacToeDialog::resetState);
    connect(buttonBox, &QDialogButtonBox::accepted, this, &TicTacToeDialog::saveState);
    connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);

    auto *mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(editor);
    mainLayout->addWidget(buttonBox);

    setWindowTitle(tr("Edit State"));
}

Dans le constructeur, nous enregistrons d'abord la référence au widget TicTacToe envoyé en paramètre, c'est-à-dire le widget dont l'état doit être modifié par l'utilisateur. Ensuite, nous créons un nouveau widget TicTacToe, et définissons son état pour qu'il soit équivalent à l'état du widget paramètre.

Enfin, nous créons les boutons et la présentation de la boîte de dialogue.

QSize TicTacToeDialog::sizeHint() const
{
    return {250, 250};
}

Nous réimplémentons la fonction sizeHint() pour nous assurer que la boîte de dialogue a une taille raisonnable.

void TicTacToeDialog::resetState()
{
    editor->clearBoard();
}

Le slot resetState() est appelé chaque fois que l'utilisateur appuie sur le bouton Reset. La seule chose que nous faisons est d'appeler la fonction clearBoard() pour le widget éditeur, c'est-à-dire le widget TicTacToe que nous avons créé dans le constructeur de la boîte de dialogue.

void TicTacToeDialog::saveState()
{

Le slot saveState() est appelé chaque fois que l'utilisateur appuie sur le bouton OK, et transfère l'état du widget éditeur au widget dont nous voulons modifier l'état. Pour que le changement d'état soit visible par Qt Widgets Designer, nous devons définir la propriété d'état de ce dernier widget à l'aide de la classe QDesignerFormWindowInterface.

QDesignerFormWindowInterface L'interface de la fenêtre de formulaire vous fournit des informations sur la fenêtre de formulaire associée et vous permet de modifier ses propriétés. L'interface n'est pas destinée à être instanciée directement, mais à fournir un accès aux fenêtres de formulaire actuelles de Qt Widgets Designer, contrôlées par le gestionnaire de fenêtres de formulaire de Qt Widgets Designer.

Si vous recherchez la fenêtre de formulaire contenant un widget spécifique, vous pouvez utiliser la fonction statique QDesignerFormWindowInterface::findFormWindow() :

    if (auto *formWindow = QDesignerFormWindowInterface::findFormWindow(ticTacToe))
        formWindow->cursor()->setProperty("state", editor->state());

Après avoir récupéré la fenêtre de formulaire du widget (dont nous voulons modifier l'état), nous utilisons la fonction QDesignerFormWindowInterface::cursor() pour récupérer le curseur de la fenêtre de formulaire.

La classe QDesignerFormWindowCursorInterface fournit une interface au curseur de texte de la fenêtre de formulaire. Une fois que nous avons le curseur, nous pouvons enfin définir la propriété state à l'aide de la fonction QDesignerFormWindowCursorInterface::setProperty().

    accept();
}

Enfin, nous appelons la fonction QEvent::accept() qui définit l'indicateur d'acceptation de l'objet événement. La définition du paramètre accept indique que le récepteur de l'événement veut l'événement. Les événements non désirés peuvent être propagés au widget parent.

Définition de la classe TicTacToe

La classe TicTacToe est un widget personnalisé qui permet à l'utilisateur de jouer au jeu du Tic-Tac-Toe.

class TicTacToe : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(QString state READ state WRITE setState)

public:
    explicit TicTacToe(QWidget *parent = nullptr);

    QSize minimumSizeHint() const override;
    QSize sizeHint() const override;
    void setState(const QString &newState);
    QString state() const;
    void clearBoard();

protected:
    void mousePressEvent(QMouseEvent *event) override;
    void paintEvent(QPaintEvent *event) override;

private:
    static constexpr char16_t Empty = '-';
    static constexpr char16_t Cross = 'X';
    static constexpr char16_t Nought = 'O';

    QRect cellRect(int position) const;
    int cellWidth() const { return width() / 3; }
    int cellHeight() const { return height() / 3; }

    QString myState;
    int turnNumber = 0;
};

Les principaux détails à observer dans la définition de la classe TicTacToe sont la déclaration de la propriété state et ses fonctions state() et setState().

Nous devons déclarer l'état du widget TicTacToe en tant que propriété pour le rendre visible à Qt Widgets Designer; ce qui permettra à Qt Widgets Designer de le gérer de la même manière qu'il gère les propriétés que le widget TicTacToe hérite de QWidget et QObject, par exemple en utilisant l'éditeur de propriétés.

Exemple de projet @ code.qt.io

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