# Programmation Qt/Le positionnement des widgets

* Avant-propos
* Introduction
* Développer pour Windows 64 bits
* Un premier programme
* Signaux et slots
* Projet Qt
* Classes et objets Qt
* Extensions du langage C++
* Utilisation de Qt Creator
** Créer un projet
* Les widgets
* Le positionnement des widgets
* La fenêtre principale
* TP : un éditeur de texte
* Traduire son programme
* Sauvegarder des données avec XML
* Sauvegarder des données avec SQL
* TP : un navigateur web
* Utilisation de Qt Designer
* Utiliser la documentation Qt
* Distribuer son programme
* Ressources
Annexes
* Avant-propos
* Introduction
* Développer pour Windows 64 bits
* Un premier programme
* Signaux et slots
* Projet Qt
* Classes et objets Qt
* Extensions du langage C++
* Utilisation de Qt Creator
** Créer un projet
* Les widgets
* Le positionnement des widgets
* La fenêtre principale
* TP : un éditeur de texte
* Traduire son programme
* Sauvegarder des données avec XML
* Sauvegarder des données avec SQL
* TP : un navigateur web
* Utilisation de Qt Designer
* Utiliser la documentation Qt
* Distribuer son programme
* Ressources
Annexes
[ Modifier le sommaire ]
Le positionnement des widgets est essentiel dans Qt. Nous travaillerons avec le positionnement absolu, et le plus utilisé, le positionnement relatif.

## Le positionnement absolu

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

### Utiliser le positionnement absolu

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

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.
Si vous utilisez la méthode setFixedSize, vous pouvez utiliser le positionnement absolu. C'est comme cela que fonctionne certains jeux.

## Le positionnement relatif

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

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

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

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

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 :
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 largeur.
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

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 :
Ce layout fonctionne de la manière suivante : avec la méthode addRow, on met le libellé du champ et le nom du champ.
C'est bien addRow et non addWidget comme les autres layouts.

### Combiner les layouts

C'est pour cela qu'on peut les combiner ! Et c'est ce principe là, qui fait la force des layouts. Ainsi, vous pouvez disposer vos widgets partout dans la page quelques soient vos envies.
On observe que la méthode pour combiner les layouts est addLayout.
La méthode addLayout existe uniquement pour les QHBoxLayout, QVBoxLayout et QGridLayout. N'utilisez donc pas cette méthode avec QFormLayout !

## En résumé

* Il existe deux positionnements : le 'positionnement absolu et le positionnement relatif. L'absolu a plusieurs défauts qui sont réglés dans le relatif, mais il est parfois plus utile que le relatif.
* Les layouts sont à la base du positionnement relatif : ils contiennent tous les widgets selon un plan précis.
* Les layouts QHBoxLayout et QVBoxLayout sont des layouts n'opérant que sur un seul axe ; il revient néanmoins plus utile dans certaines situations. On utilise la méthode addWidget pour insérer un widget.
* Le layout de grille combine les layouts horizontaux et verticaux. Il s'utilise avec la classe QGridLayout. Là aussi, la méthode addWidget s'utilise, mais avec quelques modifications : on y indique désormais le numéro de ligne et de colonne, et dans certains cas, le nombre de lignes ou de colonnes qu'occupe un seul widget ; on parle alors de spaning.
* Le layout de formulaire, utilisé avec QFormLayout, est spécialement conçu pour les formulaires. On y ajoute un champ avec la méthode addRow(label, widget).
* Enfin, les layouts se fortifient quand on les combine, avec la méthode addLayout, de même structure que addWidget.