5. Mise en page intelligente avec QLayout
Notre première application a un gros défaut : nous avons positionné ses éléments en
leur attribuant des coordonnées à la main via des instructions move(x,y). C'est
déconseillé pour plusieurs raisons :
cela oblige à faire des calculs de coordonnées assez laborieux ; les modifications
(ajout/suppression/déplacement de widgets) sont malaisées car nécessitent chaque
fois de nouveaux calculs ;
l'espace disponible défini par la taille de la fenêtre principale n'est pas
pleinement exploité ; c'est en général une donnée variable qui dépend des actions
de l'utilisateur ; par exemple, il peut redimensionner la fenêtre.
PyQt propose un mécanisme puissant pour répondre aux besoins de mise en page. Ce
mécanisme appelé gestionnaire de géométrie (geometry manager en anglais) a pour
pilier principal la classe QLayout et ses classes filles. Le principe général consiste à
regrouper les composants affichés dans des positionneurs, instances des classes filles
de QLayout définissant chacune un certain type d'alignement (vertical, horizontal,
grille, etc). Ces positionneurs, nous le verrons, peuvent être combinés hiérarchiquement
pour faire des mises en page plus complexes. À l'exécution, ils sont utilisés par PyQt
pour placer chaque composant selon la taille de leur fenêtre parente ; ces calculs sont
faits lors de la création de la fenêtre, mais aussi chaque fois que celle-ci change de
taille, typiquement suite à une action utilisateur. Grâce à QLayout, la mise en page de
chaque fenêtre peut se faire dans un style déclaratif de haut niveau, sans devoir jamais
se soucier de coordonnées ou des redimensionnements possibles.
Pour illustrer ces principes, nous allons modifier notre application en remplaçant les
coordonnées en dur par une mise en page basée sur les positionneurs. Plus précisément,
nous allons créer des alignements horizontaux et verticaux, respectivement via les
classes QHBoxLayout et QVBoxLayout. Ces classes héritent de QBoxLayout, qui
factorise les points communs aux deux types d'alignement et qui hérite elle-même de
QLayout. La première étape consiste à déterminer la structure de mise en page
souhaitée : nous décidons par exemple ici que le libellé (QLabel) doit être aligné
horizontalement avec la zone texte (QLineEdit) et que le bouton (QPushButton) doit
être aligné verticalement par rapport à ces deux éléments. Pour réaliser cela, on va
placer le libellé et la zone texte dans un QHBoxLayout (alignement horizontal) qu'on
place ensuite avec le bouton dans un QVBoxLayout (alignement vertical). Ce
78
Notre première application a un gros défaut : nous avons positionné ses éléments en
leur attribuant des coordonnées à la main via des instructions move(x,y). C'est
déconseillé pour plusieurs raisons :
cela oblige à faire des calculs de coordonnées assez laborieux ; les modifications
(ajout/suppression/déplacement de widgets) sont malaisées car nécessitent chaque
fois de nouveaux calculs ;
l'espace disponible défini par la taille de la fenêtre principale n'est pas
pleinement exploité ; c'est en général une donnée variable qui dépend des actions
de l'utilisateur ; par exemple, il peut redimensionner la fenêtre.
PyQt propose un mécanisme puissant pour répondre aux besoins de mise en page. Ce
mécanisme appelé gestionnaire de géométrie (geometry manager en anglais) a pour
pilier principal la classe QLayout et ses classes filles. Le principe général consiste à
regrouper les composants affichés dans des positionneurs, instances des classes filles
de QLayout définissant chacune un certain type d'alignement (vertical, horizontal,
grille, etc). Ces positionneurs, nous le verrons, peuvent être combinés hiérarchiquement
pour faire des mises en page plus complexes. À l'exécution, ils sont utilisés par PyQt
pour placer chaque composant selon la taille de leur fenêtre parente ; ces calculs sont
faits lors de la création de la fenêtre, mais aussi chaque fois que celle-ci change de
taille, typiquement suite à une action utilisateur. Grâce à QLayout, la mise en page de
chaque fenêtre peut se faire dans un style déclaratif de haut niveau, sans devoir jamais
se soucier de coordonnées ou des redimensionnements possibles.
Pour illustrer ces principes, nous allons modifier notre application en remplaçant les
coordonnées en dur par une mise en page basée sur les positionneurs. Plus précisément,
nous allons créer des alignements horizontaux et verticaux, respectivement via les
classes QHBoxLayout et QVBoxLayout. Ces classes héritent de QBoxLayout, qui
factorise les points communs aux deux types d'alignement et qui hérite elle-même de
QLayout. La première étape consiste à déterminer la structure de mise en page
souhaitée : nous décidons par exemple ici que le libellé (QLabel) doit être aligné
horizontalement avec la zone texte (QLineEdit) et que le bouton (QPushButton) doit
être aligné verticalement par rapport à ces deux éléments. Pour réaliser cela, on va
placer le libellé et la zone texte dans un QHBoxLayout (alignement horizontal) qu'on
place ensuite avec le bouton dans un QVBoxLayout (alignement vertical). Ce
78
