Programmation Qt/Le positionnement des widgets

Un livre de Wikilivres.
Sauter à la navigation Sauter à la recherche

Le positionnement des widgets est essentiel dans Qt. Nous travaillerons avec le positionnement absolu, et le plus utilisé, le positionnement relatif.

Le positionnement absolu[modifier | modifier le wikicode]

Le positionnement absolu est celui que nous avons vu jusqu'ici. Nous le reverrons en détail.

Utiliser le positionnement absolu[modifier | modifier le wikicode]

Nous avons plusieurs méthodes pour utiliser le positionnement absolu.

  • monWidget->move(50, 70); déplace le widget à l’abscisse (x) 50 et l'ordonnée (y) 70. Les attributs sont exprimées en pixels.
  • monWidget->setSize(24, 89); redimensionne le widget de 24 pixels de largeur et de 89 pixels de hauteur.
  • monWidget->setGeometry(50, 70, 24, 89); déplace le widget à l'abscisse 50 et à l'ordonnée 70 tout en lui donnant une largeur de 24 et une hauteur de 89.

Les défauts du positionnement absolu[modifier | modifier le wikicode]

Malheureusement, le positionnement absolu comporte des défauts. Essayez de redimensionner la fenêtre pour qu'elle soit la plus petite possible. Votre widget va se couper, ou bien, si vous faites une trèèès petite fenêtre, va disparaître ! C'est pour cela que nous allons découvrir un nouveau positionnement, le positionnement relatif.

Note : Si vous utilisez la méthode setFixedSize(), vous pouvez utiliser le positionnement absolu. C'est comme cela que fonctionne certains jeux.

Le positionnement relatif[modifier | modifier le wikicode]

Eh bien, l'heure est venue de découvrir le positionnement relatif. On utilisera 4 classes issus de QLayout : QHBoxLayout et QVBoxLayout, issues de la classe QBoxLayout (classe abstraite), QGridLayout et QFormLayout.

Principe des layouts[modifier | modifier le wikicode]

Le principe des layouts est simple : les widgets s'adaptent à la taillent de la fenêtre. Pour cela, ils utilisent des "grilles", numérotées :

Principe des layouts
0, 0 1, 0 ...
0, 1 1, 1 ...
... ... ...

Maintenant, attaquons-nous au code.

QHBoxLayout : layout horizontal[modifier | modifier le wikicode]

Dans ce premier layout, nous allons découvrir quelques méthodes, qui s'utiliseront aussi pour les autres layouts. Imaginons que vous voulez des boutons.

 1 QWidget *maPage = new QWidget(); /* Création de la page qui contiendra le layout */
 2 
 3 /* Création des boutons */
 4 QPushButton *bouton1 = new QPushButton("Wiki");
 5 QPushButton *bouton2 = new QPushButton("Books");
 6 
 7 QHBoxLayout *monLayout = new QHBoxLayout(); /* Création du layout */
 8 /* Ajout des widgets dans le layout */
 9 monLayout->addWidget(bouton1);
10 monLayout->addWidget(bouton2);
11 
12 maPage->setLayout(monLayout); /* Le layout appartient désormais à l'objet maPage */

On remarque les méthodes :

  • addWidget() : ajout d'un widget dans le layout.
  • setLayout() : définition du layout pour le widget demandé.

QVBoxLayout : layout vertical[modifier | modifier le wikicode]

Le fonctionnement de QVBoxLayout est le même que QHBoxLayout, à l’exception que cette fois-ci, c'est à la verticale. Autrement dit, je peux vous laisser remplacer les noms de classes.

QGridLayout : un layout en grille[modifier | modifier le wikicode]

Intéressants, les deux au-dessus, mais plus tard, vous aurez forcément besoin d'un layout en grille. C'est là qu'intervient QGridLayout : un layout en grille, comme le schéma du principe des layouts plus haut dans la page. Notre belle méthode addWidget() va se transformer :

 1 QPushButton *wi = new QPushButton("Wi"); /* Création des boutons */
 2 QPushButton *ki = new QPushButton("ki");
 3 QPushButton *books = new QPushButton("books");
 4 
 5 /* Introduction des boutons dans le layout */
 6 QGridLayout *m_layout = new QGridLayout();
 7 m_layout->addWidget(wi, 0, 0); /* En haut à gauche */
 8 m_layout->addWidget(ki, 1, 0); /* En haut à droite */
 9 m_layout->addWidget(books, 1, 1, 1, 2); /* En bas */
10 
11 /* Introduction du layout dans la page */
12 QWidget *m_page = new QWidget();
13 m_page->setLayout(m_layout);

Les deux premiers boutons sont tous les deux en haut, l'un à gauche et l'autre à droite. Mais le troisième bouton, lui est entièrement en bas car nous avons inséré deux nouveaux chiffres : rowSpan et columnSpan. On dit donc que le widget doit prendre 1 ligne en hauteur et 2 colonnes en hauteur. En réalité, il existe, comme on peut le voir dans la documentation, deux méthodes addWidget(). La première accepte le widget à insérer, puis les coordonnées. La deuxième, quant à elle, accepte le widget, la position x, la position y, la hauteur (rowSpan) et la largeur (columnSpan).

QFormLayout : un layout pour formulaire[modifier | modifier le wikicode]

Il se peut qu'un jour, vous voudriez mettre vos formulaires dans un layout. Mais c'est très long. C'est pour cela que QFormLayout à été créé : un layout spécialement fait pour les formulaires. Voici comment on s'en sert :

 1 /* Création des widgets */
 2 QLineEdit *nom = new QLineEdit();
 3 QLineEdit *langageProg = new QLineEdit();
 4 
 5 /* Création et introduction dans le layout */
 6 QFormLayout *monLayout = new QFormLayout();
 7 monLayout->addRow("Votre nom : ", nom);
 8 monLayout->addRow("Votre langage de programmation préféré : " langageProg);
 9 
10 /* Création et introduction dans la page **/
11 QWidget *maPage = new QWidget();
12 maPage->setLayout(monLayout);

Ce layout fonctionne de la manière suivante : avec la méthode addRow(), on met le libellé du champ et le nom du champ.

Combiner les layouts[modifier | modifier le wikicode]

C'est vite lassant un layout par programme. Imaginez un formulaire : on peut utiliser le layout adapté QFormLayout, mais pour mettre un bouton “Quitter”, et bien là, c'est compliqué. C'est pour cela qu'on peut les combiner !

 1 QLineEdit *nom = new QLineEdit();
 2 QLineEdit *prenom = new QLineEdit();
 3 
 4 QFormLayout *layoutFormulaire = new QFormLayout();
 5 layoutFormulaire->addRow("Votre nom : ", nom);
 6 layoutFormulaire->addRow("Votr prénom : ", prenom);
 7 
 8 QPushButton *boutonQuitter = new QPushButton("Quitter");
 9 
10 QVBoxLayout *layoutPrincipal = new QVBoxLayout();
11 layoutPrincipal->addLayout(layoutFormulaire); /* Utilisation de la méthode addLayout() */
12 layoutPrincipal->addWidget(boutonQuitter);
13 
14 QWidget *maPage = new QWidget();
15 maPage->setLayout(layoutPrincipal);

La méthode pour combiner les layouts est addLayout().