Sur cette page

Exemple de menus

L'exemple « Menus » montre comment utiliser les menus dans une application à fenêtre principale.

Un widget de menu peut être soit un menu déroulant dans une barre de menus, soit un menu contextuel autonome. Les menus déroulants s'affichent dans la barre de menus lorsque l'utilisateur clique sur l'élément correspondant ou appuie sur la touche de raccourci spécifiée. Les menus contextuels sont généralement invoqués à l'aide d'une touche spéciale du clavier ou d'un clic droit.

Application avec le menu Édition ouvert

Un menu se compose d’une liste d’éléments d’action. Dans les applications, de nombreuses commandes courantes peuvent être invoquées via des menus, des boutons de barre d’outils ainsi que des raccourcis clavier. Étant donné que l’utilisateur s’attend à ce que les commandes soient exécutées de la même manière, quelle que soit l’interface utilisateur utilisée, il est utile de représenter chaque commande sous forme d’action.

L'exemple « Menus » se compose d'une seule classe, ` MainWindow`, dérivée de la classe ` QMainWindow `. Lorsque l'utilisateur sélectionne l'une des actions de notre application, celle-ci affiche le chemin d'accès de l'élément dans son widget central.

Définition de la classe `MainWindow`

QMainWindow fournit une fenêtre principale d’application, avec une barre de menus, des barres d’outils, des widgets ancrés et une barre d’état entourant un grand widget central.

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow();

protected:
#ifndef QT_NO_CONTEXTMENU
    void contextMenuEvent(QContextMenuEvent *event) override;
#endif // QT_NO_CONTEXTMENU

Dans cet exemple, nous verrons comment implémenter des menus déroulants ainsi qu’un menu contextuel. Afin d’implémenter un menu contextuel personnalisé, nous devons réimplémenter la fonction ` contextMenuEvent()` de ` QWidget` pour recevoir les événements du menu contextuel destinés à notre fenêtre principale.

private slots:
    void newFile();
    void open();
    void save();
    void print();
    void undo();
    void redo();
    void cut();
    void copy();
    void paste();
    void bold();
    void italic();
    void leftAlign();
    void rightAlign();
    void justify();
    void center();
    void setLineSpacing();
    void setParagraphSpacing();
    void about();
    void aboutQt();

Nous devons également implémenter un ensemble de slots privés pour répondre à l’activation par l’utilisateur de l’une de nos entrées de menu. Notez que ces slots ne sont pas abordés dans cette documentation car ils sont triviaux : la plupart d’entre eux se contentent d’afficher le chemin de l’action dans le widget central de la fenêtre principale.

private:
    void createActions();
    void createMenus();

Nous avons choisi de simplifier le constructeur en implémentant deux fonctions privées d’aide à la création des différentes actions, à leur ajout dans les menus et à l’insertion de ces derniers dans la barre de menus de notre fenêtre principale.

    QMenu *fileMenu;
    QMenu *editMenu;
    QMenu *formatMenu;
    QMenu *helpMenu;
    QActionGroup *alignmentGroup;
    QAction *newAct;
    QAction *openAct;
    QAction *saveAct;
    QAction *printAct;
    QAction *exitAct;
    QAction *undoAct;
    QAction *redoAct;
    QAction *cutAct;
    QAction *copyAct;
    QAction *pasteAct;
    QAction *boldAct;
    QAction *italicAct;
    QAction *leftAlignAct;
    QAction *rightAlignAct;
    QAction *justifyAct;
    QAction *centerAct;
    QAction *setLineSpacingAct;
    QAction *setParagraphSpacingAct;
    QAction *aboutAct;
    QAction *aboutQtAct;
    QLabel *infoLabel;
};

Enfin, nous déclarons les différents menus et actions ainsi qu’une simple étiquette d’information dans la portée globale de l’application.

La classe ` QMenu ` fournit un widget de menu destiné à être utilisé dans les barres de menus, les menus contextuels et autres menus contextuels, tandis que la classe ` QAction ` fournit une action d’interface utilisateur abstraite pouvant être insérée dans des widgets.

Dans certaines situations, il est utile de regrouper des actions ; par exemple, nous disposons d’une action « Left Align », d’une action « Right Align », d’une action « Justify » et d’une action « Center », et nous souhaitons qu’une seule de ces actions soit active à un moment donné. Un moyen simple d’y parvenir consiste à regrouper les actions dans un groupe d’actions à l’aide de la classe « QActionGroup ».

Implémentation de la classe MainWindow

Dans le constructeur, nous commençons par créer un widget QWidget standard et en faisons le widget central de notre fenêtre principale. Notez que la fenêtre principale prend possession du pointeur du widget et le supprime au moment opportun.

MainWindow::MainWindow()
{
    QWidget *widget = new QWidget;
    setCentralWidget(widget);

    QWidget *topFiller = new QWidget;
    topFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    infoLabel = new QLabel(tr("<i>Choose a menu option, or right-click to "
                              "invoke a context menu</i>"));
    infoLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
    infoLabel->setAlignment(Qt::AlignCenter);

    QWidget *bottomFiller = new QWidget;
    bottomFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->setContentsMargins(5, 5, 5, 5);
    layout->addWidget(topFiller);
    layout->addWidget(infoLabel);
    layout->addWidget(bottomFiller);
    widget->setLayout(layout);

Nous créons ensuite l’étiquette d’information ainsi que des éléments de remplissage supérieur et inférieur que nous ajoutons à une mise en page que nous installons sur le widget central. Les objets ` QMainWindow ` sont fournis avec leur propre mise en page personnalisée ; définir une mise en page sur la fenêtre principale elle-même, ou créer une mise en page dont la fenêtre principale est le parent, est considéré comme une erreur. Vous devez toujours définir votre propre mise en page sur le widget central à la place.

    createActions();
    createMenus();

    QString message = tr("A context menu is available by right-clicking");
    statusBar()->showMessage(message);

    setWindowTitle(tr("Menus"));
    setMinimumSize(160, 160);
    resize(480, 320);
}

Pour créer les actions et les menus, nous appelons nos deux fonctions utilitaires : ` createActions() ` et ` createMenus()`. Nous y reviendrons dans un instant.

QMainWindowLa fonction ` statusBar()` renvoie la barre d’état de la fenêtre principale (si la barre d’état n’existe pas, cette fonction en créera une et renverra une barre d’état vide). Nous initialisons la barre d’état et le titre de la fenêtre, redimensionnons la fenêtre à une taille appropriée et nous assurons que la fenêtre principale ne puisse pas être redimensionnée à une taille inférieure à celle spécifiée.

Examinons maintenant de plus près la fonction de commodité ` createActions() ` qui crée les différentes actions :

void MainWindow::createActions()
{
    newAct = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::DocumentNew),
                         tr("&New"), this);
    newAct->setShortcuts(QKeySequence::New);
    newAct->setStatusTip(tr("Create a new file"));
    connect(newAct, &QAction::triggered, this, &MainWindow::newFile);
    ...

Un objet ` QAction ` peut contenir une icône, un texte, un raccourci, une info-bulle d’état, un texte « Qu’est-ce que c’est ? » et une info-bulle. La plupart de ces éléments peuvent être définis dans le constructeur, mais ils peuvent également être définis indépendamment à l’aide des fonctions pratiques fournies.

Dans la fonction ` createActions() `, nous créons d’abord une action ` newAct `, en lui transmettant le texte et une icône à l’aide de l’une des constantes d’icône du thème. Nous définissons ` Ctrl+N ` comme raccourci à l’aide de la fonction ` QAction::setShortcut()` et nous définissons son info-bulle à l’aide de la fonction ` QAction::setStatusTip()` (l’info-bulle s’affiche sur toutes les barres d’état fournies par le widget parent de niveau supérieur de l’action). Nous connectons également son signal ` triggered()` au slot ` newFile() `.

Les autres actions sont créées de la même manière. Veuillez consulter le code source pour plus de détails.

    alignmentGroup = new QActionGroup(this);
    alignmentGroup->addAction(leftAlignAct);
    alignmentGroup->addAction(rightAlignAct);
    alignmentGroup->addAction(justifyAct);
    alignmentGroup->addAction(centerAct);
    leftAlignAct->setChecked(true);
}

Une fois que nous avons créé les actions « Left Align », « Right Align », « Justify » et « Center », nous pouvons également créer le groupe d’actions mentionné précédemment.

Chaque action est ajoutée au groupe à l’aide de la fonction addAction() de QActionGroup. Notez qu’une action peut également être ajoutée à un groupe en la créant avec ce groupe comme parent. Un groupe d’actions étant exclusif par défaut, une seule des actions du groupe est cochée à la fois (ceci peut être modifié à l’aide de la fonction QActionGroup::setExclusive()).

Une fois toutes les actions créées, nous utilisons la fonction ` createMenus() ` pour ajouter les actions aux menus et insérer ces derniers dans la barre de menus :

void MainWindow::createMenus()
{
    fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(newAct);
    fileMenu->addAction(openAct);
    fileMenu->addAction(saveAct);
    fileMenu->addAction(printAct);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAct);

    editMenu = menuBar()->addMenu(tr("&Edit"));
    editMenu->addAction(undoAct);
    editMenu->addAction(redoAct);
    editMenu->addSeparator();
    editMenu->addAction(cutAct);
    editMenu->addAction(copyAct);
    editMenu->addAction(pasteAct);
    editMenu->addSeparator();

    helpMenu = menuBar()->addMenu(tr("&Help"));
    helpMenu->addAction(aboutAct);
    helpMenu->addAction(aboutQtAct);

QMenuBarLa fonction ` addMenu()` ajoute un nouvel ` QMenu ` portant le titre spécifié à la barre de menus (notez que la barre de menus devient propriétaire du menu). Nous utilisons la fonction ` addAction()` de ` QWidget` pour ajouter chaque action au menu correspondant.

Par ailleurs, la classe ` QMenu ` fournit plusieurs fonctions pratiques ` addAction()` qui créent et ajoutent de nouvelles actions à partir de textes et/ou d’icônes fournis. Vous pouvez également fournir un membre qui se connectera automatiquement au signal ` triggered()` de la nouvelle action, ainsi qu’un raccourci représenté par une instance de ` QKeySequence `.

La fonction ` QMenu::addSeparator()` crée et renvoie une nouvelle action de séparation, c’est-à-dire une action pour laquelle ` QAction::isSeparator()` renvoie `true`, et ajoute cette nouvelle action à la liste des actions du menu.

    formatMenu = editMenu->addMenu(tr("&Format"));
    formatMenu->addAction(boldAct);
    formatMenu->addAction(italicAct);
    formatMenu->addSeparator()->setText(tr("Alignment"));
    formatMenu->addAction(leftAlignAct);
    formatMenu->addAction(rightAlignAct);
    formatMenu->addAction(justifyAct);
    formatMenu->addAction(centerAct);
    formatMenu->addSeparator();
    formatMenu->addAction(setLineSpacingAct);
    formatMenu->addAction(setParagraphSpacingAct);
}

Notez le menu « Format ». Tout d’abord, il est ajouté en tant que sous-menu au menu « Edit » à l’aide de la fonction ` addMenu()` de ` QMenu`. Ensuite, observez les actions d’alignement : dans la fonction ` createActions() `, nous avons ajouté les actions ` leftAlignAct`, ` rightAlignAct`, ` justifyAct ` et ` centerAct ` à un groupe d’actions. Néanmoins, nous devons ajouter chaque action au menu séparément, tandis que le groupe d’actions fait son travail en arrière-plan.

#ifndef QT_NO_CONTEXTMENU
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(this);
    menu.addAction(cutAct);
    menu.addAction(copyAct);
    menu.addAction(pasteAct);
    menu.exec(event->globalPos());
}
#endif // QT_NO_CONTEXTMENU

Pour proposer un menu contextuel personnalisé, nous devons réimplémenter la fonction contextMenuEvent() de QWidget afin de recevoir les événements du menu contextuel du widget (notez que l’implémentation par défaut ignore simplement ces événements).

Chaque fois que nous recevons un tel événement, nous créons un menu contenant les actions Cut, Copy et Paste. Les menus contextuels peuvent être exécutés soit de manière asynchrone à l’aide de la fonction ` popup()``, soit de manière synchrone à l’aide de la fonction ` exec()`. Dans cet exemple, nous avons choisi d’afficher le menu à l’aide de sa fonction ` exec()`. En passant la position de l’événement en argument, nous nous assurons que le menu contextuel s’affiche à l’emplacement prévu.

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.