Attaquons sans plus tarder l'étude de nos premiers layouts (les plus simples), vous allez mieux comprendre à quoi tout cela sert
Nous allons travailler sur 2 classes :
QHBoxLayout et QVBoxLayout héritent de
QBoxLayout. Ce sont des classes très similaires (la doc Qt parle de "
convenience classes", des classes qui sont là pour vous aider à aller plus vite mais qui sont en fait quasiment identiques à QBoxLayout).
Nous n'allons pas utiliser QBoxLayout, mais juste ses classes filles QHBoxLayout et QVBoxLayout (ça revient au même).
Le layout horizontal
L'utilisation d'un layout se fait en 3 temps :
- On crée les widgets
- On crée le layout et on place les widgets dedans
- On dit à la fenêtre d'utiliser le layout qu'on a créé
1/ Créer les widgets
Pour les besoins de ce tutoriel, nous allons créer plusieurs boutons de type QPushButton :
Code : C++1
2
3 | QPushButton *bouton1 = new QPushButton("Bonjour");
QPushButton *bouton2 = new QPushButton("les");
QPushButton *bouton3 = new QPushButton("Zéros");
|
Vous remarquerez que j'utilise des pointeurs. En effet, j'aurais très bien pu faire sans pointeurs comme ceci :
Code : C++1
2
3 | QPushButton bouton1("Bonjour");
QPushButton bouton2("les");
QPushButton bouton3("Zéros");
|
... cette méthode a l'air plus simple, mais vous verrez que c'est plus pratique de travailler directement avec des pointeurs par la suite

La différence entre ces 2 codes, c'est que bouton1 est un pointeur dans le premier code, tandis que c'est un objet dans le second code.
On va donc utiliser la première méthode avec les pointeurs.
Bon, on a 3 boutons, c'est bien. Mais les plus perspicaces d'entre vous auront remarqué qu'on n'a pas indiqué quelle était la fenêtre parente, comme on aurait fait avant :
Code : C++1 | QPushButton *bouton1 = new QPushButton("Bonjour", &fenetre);
|
On n'a pas fait comme ça, et c'est fait exprès justement. Nous n'allons pas placer les boutons dans la fenêtre directement, mais dans un conteneur : le layout.
2/ Créer le layout et placer les widgets dedans
Créons justement ce layout, un layout horizontal :
Code : C++1 | QHBoxLayout *layout = new QHBoxLayout;
|
Le constructeur de cette classe est simple, on n'a pas besoin d'indiquer de paramètre.
Maintenant que notre layout est créé, rajoutons nos widgets à l'intérieur :
Code : C++1
2
3 | layout->addWidget(bouton1);
layout->addWidget(bouton2);
layout->addWidget(bouton3);
|
La méthode addWidget du layout attend que vous lui donniez en paramètre un pointeur vers le widget à ajouter au conteneur. Voilà pourquoi je vous ai fait utiliser des pointeurs (sinon il aurait fallu écrire
layout->addWidget(&bouton1);
à chaque fois).
3/ Indiquer à la fenêtre d'utiliser le layout
Maintenant, dernière chose : il faut placer le layout dans la fenêtre. Il faut dire à la fenêtre : "
tu vas utiliser ce layout, qui contient mes widgets".
Code : C++1 | fenetre.setLayout(layout);
|
La méthode setLayout de la fenêtre attend un pointeur vers le layout à utiliser.
Et voilà, notre fenêtre contient maintenant notre layout, qui contient les widgets. Le layout se chargera d'organiser les widgets horizontalement tout seul.
Résumé du code
Voici le code complet de notre fichier main.cpp :
Code : C++ 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | #include <QApplication>
#include <QPushButton>
#include <QHBoxLayout>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget fenetre;
QPushButton *bouton1 = new QPushButton("Bonjour");
QPushButton *bouton2 = new QPushButton("les");
QPushButton *bouton3 = new QPushButton("Zéros");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(bouton1);
layout->addWidget(bouton2);
layout->addWidget(bouton3);
fenetre.setLayout(layout);
fenetre.show();
return app.exec();
}
|
J'ai surligné les principales nouveautés.
En particulier, comme d'hab' lorsque vous utilisez une nouvelle classe Qt, pensez à l'inclure au début de votre code :
#include <QHBoxLayout>
Résultat
Voilà à quoi ressemble la fenêtre maintenant que l'on utilise un layout horizontal :
Les boutons sont automatiquement disposés de manière horizontale !
L'intérêt principal du layout, c'est son comportement face aux redimensionnements de la fenêtre.
Essayons de l'élargir :
Les boutons continuent de prendre l'espace en largeur.
On peut aussi l'agrandir en hauteur :
On remarque que les widgets restent centrés verticalement.
Vous pouvez aussi essayer de réduire la taille de la fenêtre. On vous interdira de la réduire si les boutons ne peuvent plus être affichés, ce qui vous garantit que les boutons ne risquent plus de disparaître comme avant !
Schéma des conteneurs
En résumé, la fenêtre contient le layout qui contient les widgets. Le layout se charge d'organiser les widgets.
Schématiquement, ça se passe donc comme ça :
Le layout est invisible à l'affichage
On vient de voir le layout QHBoxLayout qui organise les widgets horizontalement.
Il y en a un autre qui les organise verticalement (c'est quasiment la même chose) : QVBoxLayout.
Le layout vertical
Pour utiliser un layout vertical, il suffit de remplacer QHBoxLayout par QVBoxLayout dans le code précédent. Oui oui, c'est aussi simple que ça
Code : C++ 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | #include <QApplication>
#include <QPushButton>
#include <QVBoxLayout>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget fenetre;
QPushButton *bouton1 = new QPushButton("Bonjour");
QPushButton *bouton2 = new QPushButton("les");
QPushButton *bouton3 = new QPushButton("Zéros");
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(bouton1);
layout->addWidget(bouton2);
layout->addWidget(bouton3);
fenetre.setLayout(layout);
fenetre.show();
return app.exec();
}
|
N'oubliez pas d'inclure QVBoxLayout.
Compilez et exécutez ce code, et admirez le résultat :
Amusez-vous à redimensionner la fenêtre. Vous voyez là encore que la layout adapte les widgets qu'il contient à toutes les dimensions. Il empêche en particulier la fenêtre de devenir trop petite, ce qui aurait empêché l'affichage des boutons.
La suppression automatique des widgets
Eh ! Je viens de me rendre compte que tu fais des new dans tes codes, mais il n'y a pas de delete ! Si tu alloues des objets sans les supprimer, ils vont pas rester en mémoire ?
Si, mais comme je vous l'avais dit plus tôt, Qt est intelligent

En fait, les widgets sont placés dans un layout, qui est lui-même placé dans la fenêtre. Lorsque la fenêtre est supprimée (ici à la fin du programme), tous les widgets contenus dans son layout sont supprimés par Qt.
C'est donc Qt qui se charge de faire les delete pour nous.
Bien, vous devriez commencer à comprendre comment fonctionnent les layouts
Comme on l'a vu au début du chapitre, il y a de nombreux layouts, qui ont chacun leurs spécificités ! Intéressons-nous maintenant au puissant (mais complexe) QGridLayout.