trouver un expert Python
Les gestionnaires de mise en page de PyQt offrent un moyen convivial et productif d’organiser les composants graphiques, ou widgets, sur une interface graphique. La disposition correcte des widgets donnera à vos applications GUI un aspect soigné et professionnel. Apprendre à le faire de manière efficace et efficiente est une compétence fondamentale pour vous familiariser avec le développement d'applications GUI à l'aide de Python et PyQt.
Dans ce didacticiel, vous apprendrez:
- Quels sont les avantages de l’utilisation de PyQt gestionnaires de mise en page
- Comment procéder par programmation mettre en page des widgets sur une interface graphique utilisant les gestionnaires de disposition de PyQt
- Comment sélectionnez le bon gestionnaire de mise en page pour votre application GUI
- Comment disposer les widgets dans basé sur la fenêtre principale et basé sur le dialogue applications
Grâce à ces connaissances et à ces compétences, vous pourrez utiliser Python et PyQt pour créer des applications GUI d’aspect professionnel.
Pour une meilleure compréhension de l'utilisation des gestionnaires de disposition, des connaissances préalables sur la création d'applications d'interface graphique PyQt et l'utilisation des widgets PyQt seraient utiles.
Bonus gratuit: 5 Réflexions sur la maîtrise de Python, un cours gratuit pour les développeurs Python qui vous montre la feuille de route et l'état d'esprit dont vous aurez besoin pour faire passer vos compétences Python au niveau supérieur.
Disposition des éléments graphiques sur une interface graphique
Lorsque vous créez des applications d'interface utilisateur graphique (GUI), un problème courant est de savoir comment disposer vos composants graphiques (boutons, menus, barres d'outils, étiquettes, etc.) de manière cohérente sur vos formulaires et fenêtres. Ce processus est connu sous le nom de Disposition GUI, et c'est une étape importante dans la création d'applications GUI.
Dans le passé, si vous vouliez disposer des composants graphiques, ou des widgets, sur une fenêtre, vous suiviez l'une des approches suivantes:
- Décidez et définissez manuellement une taille et une position statiques pour chaque widget dans la fenêtre.
- Calculez et définissez dynamiquement la taille et la position de chaque widget.
La première approche est assez directe, mais elle présente au moins les inconvénients suivants:
- Vos fenêtres seront non redimensionnable, ce qui pourrait poser des problèmes lors de leur affichage sur différentes résolutions d'écran.
- Vos libellés peuvent ne pas prendre en charge localisation correctement parce que la longueur d'un texte donné change d'une langue à l'autre.
- Vos widgets s'afficheront différemment sur différentes plates-formes, ce qui rend l'écriture difficile multi plateforme des applications qui ont l'air bien.
La deuxième approche est plus flexible. Cependant, il présente également des inconvénients:
- Vous devez faire beaucoup de calculs manuels pour déterminer le bon Taille et position de chaque widget.
- Vous devez faire quelques calculs supplémentaires pour répondre correctement à redimensionnement de la fenêtre.
- Vous devez refaire tous les calculs à tout moment modifier la mise en page de votre fenêtre.
Même si vous pouvez toujours utiliser l’une de ces deux approches pour mettre en page vos interfaces graphiques, la plupart du temps, vous souhaiterez utiliser une troisième approche plus pratique mise en œuvre par la plupart des cadres d’interface graphique ou des boîtes à outils modernes: les gestionnaires de disposition.
Remarque: Dans certains cadres d'interface graphique, tels que Tkinter, les gestionnaires de disposition sont également appelés gestionnaires de géométrie.
Les gestionnaires de mise en page organisent automatiquement les widgets sur une interface graphique en fonction de vos besoins spécifiques. Ils évitent les inconvénients de compatibilité de la première approche ainsi que les calculs ennuyeux et compliqués de la seconde approche.
Dans les sections suivantes, vous découvrirez les gestionnaires de disposition intégrés de PyQt et comment les utiliser pour mettre en page efficacement les composants graphiques de vos applications GUI.
Se procurer avec une galerie de mises en page PyQt
Dans PyQt, les widgets sont des composants graphiques que vous utilisez comme blocs de construction pour vos applications GUI. Lorsque vous placez un tas de widgets sur une fenêtre pour créer une interface graphique, vous devez leur donner un peu d'ordre. Vous devez définir la taille et la position des widgets sur la fenêtre, et vous devez également définir leur comportement lorsque l'utilisateur redimensionne la fenêtre sous-jacente.
Pour organiser les widgets sur des fenêtres ou des formulaires dans PyQt, vous pouvez utiliser les techniques suivantes:
- Utilisation
.resize ()
et.bouge toi()
sur vos widgets pour fournir une taille et une position absolues. - Réimplémentation
.resizeEvent ()
et calculez la taille et la position de vos widgets de manière dynamique. - Utilisez les gestionnaires de mise en page et laissez-les faire tous les calculs et travailler dur pour vous.
Ces techniques correspondent généralement aux trois approches différentes pour la mise en page d'une interface graphique que vous avez vues dans la section précédente.
Encore une fois, calculer dynamiquement la taille et la position peut être une bonne approche, mais la plupart du temps, il vaut mieux utiliser les gestionnaires de mise en page. Dans PyQt, les gestionnaires de disposition sont des classes qui fournissent les fonctionnalités requises pour gérer automatiquement la taille, la position et le comportement de redimensionnement des widgets dans la disposition.
Avec les gestionnaires de mise en page, vous pouvez organiser automatiquement enfant widgets dans n'importe quel parent, ou conteneur, widget. L'utilisation de gestionnaires de mise en page garantira que vous utiliserez au mieux l'espace disponible sur votre interface graphique et que votre application reste utilisable lorsque l'utilisateur redimensionne la fenêtre.
Les gestionnaires de mise en page fonctionnent comme des conteneurs pour les widgets et d'autres mises en page. Pour ajouter des widgets à un gestionnaire de mise en page, vous appelez .addWidget ()
sur la mise en page à portée de main. Pour ajouter une mise en page à une autre mise en page, vous appelez .addLayout ()
sur la mise en page à portée de main. Vous plongerez plus profondément dans l'imbrication des dispositions dans la section Imbrication des dispositions pour créer des interfaces graphiques complexes.
Une fois que vous avez ajouté tous les widgets requis à un gestionnaire de disposition, vous définissez le gestionnaire de disposition sur un widget donné à l'aide de .setLayout ()
. Vous pouvez définir un gestionnaire de mise en page sur toutes les sous-classes de QWidget
, y compris les fenêtres ou les formulaires.
Tous les widgets d'une mise en page sont automatiquement définis comme enfants du widget sur lequel vous installez la mise en page, et non de la mise en page elle-même. En effet, les widgets ne peuvent avoir que d’autres widgets, et non des mises en page, comme parent.
Les gestionnaires de mise en page de PyQt fournissent des fonctionnalités intéressantes qui vous facilitent la vie lorsqu'il s'agit de créer de belles applications GUI:
- Manipuler le Taille et position de widgets sans aucun calcul
- Manipuler le redimensionnement et repositionnement du widget lorsque l'utilisateur redimensionne la fenêtre sous-jacente
- Redimensionner les étiquettes pour une meilleure prise en charge internationalisation
- Fournir une disposition de fenêtre native pour multi plateforme applications
L'utilisation de gestionnaires de disposition augmentera également considérablement votre productivité et améliorera la maintenabilité de votre code à long terme.
PyQt fournit quatre classes de gestionnaire de mise en page à usage général:
QHBoxLayout
organise les widgets dans une boîte horizontale.QVBoxLayout
organise les widgets dans une boîte verticale.QGridLayout
organise les widgets dans une grille.QFormLayout
organise les widgets sur deux colonnes.
Dans les sections suivantes, vous apprendrez les bases de l’utilisation de ces gestionnaires de mise en page à usage général.
Utilisation des gestionnaires de mise en page à usage général
Lors de la création d'applications GUI avec PyQt, vous utiliserez souvent une ou plusieurs des quatre mises en page à usage général que vous avez vues à la fin de la section précédente pour que votre widget soit disposé sur vos fenêtres et formulaires.
Dans les prochaines sections, vous apprendrez à créer et à utiliser les quatre gestionnaires de mise en page à usage général à l'aide de quelques exemples.
Création de dispositions horizontales: QHBoxLayout
Gestionnaires de disposition de boîte prendre l'espace qu'ils obtiennent de leur mise en page ou widget parent, le diviser en plusieurs cases, ou celluleset faites en sorte que chaque widget de la mise en page remplisse une case.
QHBoxLayout
est l'une des deux mises en page de boîte disponibles dans PyQt. Ce gestionnaire de mise en page vous permet d'organiser des widgets horizontalement, l'un à côté de l'autre. Les widgets sont ajoutés à la mise en page de gauche à droite. Cela signifie que le widget que vous ajoutez en premier dans votre code sera le widget le plus à gauche de la mise en page.
Pour ajouter des widgets à un QHBoxLayout
objet, vous appelez .addWidget (widget, étirement, alignement)
sur l'objet de mise en page. Cette méthode prend un argument obligatoire et deux arguments facultatifs:
-
widget
est un argument obligatoire qui contient le widget spécifique que vous souhaitez ajouter à la mise en page. -
étendue
est un argument facultatif contenant un nombre entier représentant le facteur d'étirement à appliquerwidget
. Les widgets avec des facteurs d'étirement plus élevés se développent davantage lors du redimensionnement de la fenêtre. Il est par défaut0
, ce qui signifie que le widget n'a pas de facteur d'étirement attribué. -
alignement
est un argument facultatif qui contient des indicateurs horizontaux et verticaux. Vous pouvez combiner ces indicateurs pour produire l'alignement souhaité du widget à l'intérieur de sa cellule contenant. Il est par défaut0
, ce qui signifie que le widget remplira toute la cellule.
Voici une petite application qui montre comment créer une mise en page horizontale à l'aide de QHBoxLayout
. Dans cet exemple, vous utiliserez QPushButton
des objets pour mieux visualiser où chaque widget sera placé dans la mise en page selon l'ordre dans lequel vous ajoutez les widgets à votre code:
1importer sys
2
3de PyQt5.QtWidgets importer (
4 QApplication,
5 QHBoxLayout,
6 QPushButton,
sept QWidget,
8)
9
dixclasse La fenêtre(QWidget):
11 def __init__(soi):
12 super().__init__()
13 soi.setWindowTitle("Exemple de QHBoxLayout")
14 # Créer une instance QHBoxLayout
15 disposition = QHBoxLayout()
16 # Ajouter des widgets à la mise en page
17 disposition.addWidget(QPushButton("Le plus à gauche"))
18 disposition.addWidget(QPushButton("Centre"), 1)
19 disposition.addWidget(QPushButton("Le plus à droite"), 2)
20 # Définir la mise en page sur la fenêtre de l'application
21 soi.setLayout(disposition)
22 impression(soi.les enfants())
23
24si __Nom__ == "__principale__":
25 app = QApplication(sys.argv)
26 la fenêtre = La fenêtre()
27 la fenêtre.montrer()
28 sys.sortie(app.exec_())
À la ligne 15, vous créez un QHBoxLayout
objet appelé disposition
. Aux lignes 17 à 19, vous ajoutez trois boutons à disposition
en utilisant .addWidget ()
. Notez que vous passez 1
et 2
à la étendue
paramètre dans le Centre et Tout à droite boutons, respectivement. À la ligne 21, vous définissez disposition
comme disposition de premier niveau de votre fenêtre en utilisant .setLayout ()
.
Si vous exécutez cette application, la fenêtre suivante s’affiche à l’écran:

Cette fenêtre contient trois boutons disposés horizontalement. Notez que le Le plus à gauche bouton correspond au premier bouton que vous ajoutez dans votre code. Ainsi, les boutons sont affichés dans le même ordre (de gauche à droite) que vous les ajoutez dans votre code (de haut en bas).
le Centre et Tout à droite les boutons ont des facteurs d'étirement différents, de sorte qu'ils s'étendent proportionnellement à ces facteurs lorsque vous redimensionnez la fenêtre.
De plus, tous les boutons de disposition
et la mise en page elle-même est définie comme enfants de La fenêtre
. Cette opération est effectuée automatiquement par l'objet layout, qui appelle en interne .setParent ()
sur chaque widget. L'appel à impression()
à la ligne 17 imprime une liste des enfants de La fenêtre
sur votre terminal comme preuve de ce comportement.
Création de dispositions verticales: QVBoxLayout
QVBoxLayout
organise les widgets verticalement, l'un en dessous de l'autre. Vous pouvez utiliser cette classe pour créer des dispositions verticales et organiser vos widgets de haut en bas. Depuis QVBoxLayout
est une autre disposition de boîte, son .addWidget ()
la méthode fonctionne de la même manière que dans QHBoxLayout
.
Voici une application PyQt qui montre comment créer et utiliser un QVBoxLayout
objet pour créer des arrangements verticaux de widgets dans vos interfaces graphiques:
1importer sys
2
3de PyQt5.QtWidgets importer (
4 QApplication,
5 QPushButton,
6 QVBoxLayout,
sept QWidget,
8)
9
dixclasse La fenêtre(QWidget):
11 def __init__(soi):
12 super().__init__()
13 soi.setWindowTitle("Exemple de QVBoxLayout")
14 soi.redimensionner(270, 110)
15 # Créer une instance QVBoxLayout
16 disposition = QVBoxLayout()
17 # Ajouter des widgets à la mise en page
18 disposition.addWidget(QPushButton("Haut"))
19 disposition.addWidget(QPushButton("Centre"))
20 disposition.addWidget(QPushButton("Bas"))
21 # Définir la mise en page sur la fenêtre de l'application
22 soi.setLayout(disposition)
23
24si __Nom__ == "__principale__":
25 app = QApplication(sys.argv)
26 la fenêtre = La fenêtre()
27 la fenêtre.montrer()
28 sys.sortie(app.exec_())
À la ligne 16, vous créez une instance de QVBoxLayout
. Aux lignes 18 à 20, vous ajoutez trois boutons à disposition
. Enfin, vous définissez disposition
comme disposition de premier niveau de votre fenêtre.
Si vous exécutez cette application, vous obtiendrez la fenêtre suivante:

Votre fenêtre affiche trois boutons dans une disposition verticale, l'un en dessous de l'autre. Les boutons apparaissent dans le même ordre (de haut en bas) que vous les ajoutez dans votre code (de haut en bas).
Organisation des widgets dans une grille: QGridLayout
Vous pouvez utiliser QGridLayout
pour organiser les widgets dans un la grille de lignes et de colonnes. Chaque widget aura une position relative dans la grille. Pour définir la position d'un widget ou d'une cellule dans la grille, vous utilisez une paire de coordonnées du formulaire (ligne, colonne)
. Ces coordonnées doivent être des nombres entiers de base zéro.
QGridLayout
prend l'espace disponible sur son parent, le divise en lignes et colonnes, et place chaque widget dans sa propre cellule ou boîte. QGridLayout
détermine automatiquement le nombre de lignes et de colonnes de la mise en page finale en fonction du nombre de widgets et de leurs coordonnées. Si vous n'ajoutez pas de widget à une cellule donnée, alors QGridLayout
laissera cette cellule vide.
Pour ajouter des widgets à une disposition de grille, vous appelez .addWidget ()
sur la mise en page. Cette méthode a deux implémentations surchargées différentes:
addWidget (widget, ligne, colonne, alignement)
ajoutewidget
à la cellule à (rangée
,colonne
).addWidget (widget, fromRow, fromColumn, rowSpan, columnSpan, alignement)
ajoutewidget
à la cellule, couvrant plusieurs lignes, colonnes ou les deux.
La première implémentation prend les arguments suivants:
widget
est un argument obligatoire qui contient le widget spécifique que vous devez ajouter à la mise en page.rangée
est un argument obligatoire contenant un entier représentant la coordonnée d'une ligne dans la grille.colonne
est un argument obligatoire contenant un entier représentant la coordonnée d'une colonne dans la grille.alignement
est un argument facultatif qui contient l'alignement du widget à l'intérieur de sa cellule contenant. Il est par défaut0
, ce qui signifie que le widget remplira toute la cellule.
Voici un exemple d'utilisation QGridLayout
pour créer une grille de widgets:
1importer sys
2
3de PyQt5.QtWidgets importer (
4 QApplication,
5 QGridLayout,
6 QPushButton,
sept QWidget,
8)
9
dixclasse La fenêtre(QWidget):
11 def __init__(soi):
12 super().__init__()
13 soi.setWindowTitle(«Exemple QGridLayout»)
14 # Créer une instance QGridLayout
15 disposition = QGridLayout()
16 # Ajouter des widgets à la mise en page
17 disposition.addWidget(QPushButton("Bouton à (0, 0)"), 0, 0)
18 disposition.addWidget(QPushButton("Bouton à (0, 1)"), 0, 1)
19 disposition.addWidget(QPushButton("Bouton à (0, 2)"), 0, 2)
20 disposition.addWidget(QPushButton("Bouton à (1, 0)"), 1, 0)
21 disposition.addWidget(QPushButton("Bouton sur (1, 1)"), 1, 1)
22 disposition.addWidget(QPushButton("Bouton en (1, 2)"), 1, 2)
23 disposition.addWidget(QPushButton("Bouton à (2, 0)"), 2, 0)
24 disposition.addWidget(QPushButton("Bouton en (2, 1)"), 2, 1)
25 disposition.addWidget(QPushButton("Bouton en (2, 2)"), 2, 2)
26 # Définir la mise en page sur la fenêtre de l'application
27 soi.setLayout(disposition)
28
29si __Nom__ == "__principale__":
30 app = QApplication(sys.argv)
31 la fenêtre = La fenêtre()
32 la fenêtre.montrer()
33 sys.sortie(app.exec_())
À la ligne 15, vous créez le QGridLayout
objet. Ensuite, aux lignes 17 à 25, vous ajoutez des widgets à la mise en page en utilisant .addWidget ()
. Pour voir comment les mises en page de grille gèrent les cellules sans widget attribué, commentez une ou plusieurs de ces lignes et exécutez à nouveau l'application.
Si vous exécutez ce code à partir de votre ligne de commande, vous obtiendrez une fenêtre comme celle-ci:

Chaque widget dans le QGridLayout
objet occupe la cellule définie par la paire de coordonnées que vous fournissez dans .addWidget ()
. Le texte de chaque bouton reflète ces coordonnées. Les coordonnées sont basées sur zéro, donc la première cellule est à (0, 0)
.
Dans la deuxième implémentation de .addWidget ()
, les arguments widget
et alignement
restez le même, et vous avez quatre arguments supplémentaires qui vous permettent de placer le widget sur plusieurs lignes ou colonnes:
fromRow
prend un nombre entier qui représente la ligne dans laquelle le widget commencera.fromColumn
prend un nombre entier qui représente la colonne dans laquelle le widget démarrera.rowSpan
prend un nombre entier qui représente le nombre de lignes que le widget occupera dans la grille.columnSpan
prend un nombre entier qui représente le nombre de colonnes que le widget occupera dans la grille.
Voici une application qui montre comment cette variante de .addWidget ()
travaux:
1importer sys
2
3de PyQt5.QtWidgets importer (
4 QApplication,
5 QGridLayout,
6 QPushButton,
sept QWidget,
8)
9
dixclasse La fenêtre(QWidget):
11 def __init__(soi):
12 super().__init__()
13 soi.setWindowTitle(«Exemple QGridLayout»)
14 # Créer une instance QGridLayout
15 disposition = QGridLayout()
16 # Ajouter des widgets à la mise en page
17 disposition.addWidget(QPushButton("Bouton à (0, 0)"), 0, 0)
18 disposition.addWidget(QPushButton("Bouton sur (0, 1)"), 0, 1)
19 disposition.addWidget(QPushButton("Le bouton s'étend sur deux colonnes"), 1, 0, 1, 2)
20 # Définir la mise en page sur la fenêtre de l'application
21 soi.setLayout(disposition)
22
23si __Nom__ == "__principale__":
24 app = QApplication(sys.argv)
25 la fenêtre = La fenêtre()
26 la fenêtre.montrer()
27 sys.sortie(app.exec_())
À la ligne 19, vous utilisez la deuxième implémentation de .addWidget ()
pour ajouter un bouton qui occupe deux colonnes dans la grille. Le bouton commence à la deuxième ligne (fromRow = 1
) et à la première colonne (fromColumn = 0
). Enfin, le bouton occupe une ligne (rowSpan = 1
) et deux colonnes (columnSpan = 2
).
Remarque: Étant donné que PyQt est une liaison Python pour Qt, qui est un ensemble de bibliothèques C ++, vous ne pouvez pas utiliser d'arguments de mot-clé lors de l'appel des méthodes PyQt. Les arguments de mot-clé utilisés dans le paragraphe ci-dessus ont pour seul but de montrer quelle valeur est attribuée à chaque argument.
Voici la fenêtre que vous verrez sur votre écran si vous exécutez cette application:

Dans ce type de mise en page, vous pouvez faire en sorte qu'un widget occupe plus d'une cellule, comme vous l'avez fait avec le Le bouton s'étend sur deux cols bouton.
Créer rapidement des formulaires: QFormLayout
Si vous créez constamment des formulaires pour effectuer des actions telles que la saisie de données dans une base de données, alors QFormLayout
est pour toi. Cette classe organise les widgets dans un deux colonnes disposition. La première colonne affiche généralement un étiquette décrivant l'entrée prévue, et la deuxième colonne contient généralement widgets d'entrée tel que QLineEdit
, QComboBox
, ou QSpinBox
qui permettent à l'utilisateur de saisir ou de modifier des données.
Pour ajouter des widgets à une mise en page de formulaire, vous utilisez .ajouter une rangée()
. Cette méthode comporte plusieurs variantes mais, la plupart du temps, vous aurez le choix entre les deux suivantes:
-
.addRow (étiquette, champ)
ajoute une nouvelle ligne au bas d'une mise en page de formulaire. La ligne doit contenir unQLabel
objet (étiquette
) et un widget d'entrée (champ
). -
.addRow (labelText, champ)
crée et ajoute automatiquement un nouveauQLabel
objet aveclabelText
comme son texte.champ
contient un widget d'entrée.
Voici un exemple d'application utilisant un QFormLayout
objet pour organiser les widgets:
1importer sys
2
3de PyQt5.QtWidgets importer (
4 QApplication,
5 QFormLayout,
6 QLabel,
sept QLineEdit,
8 QWidget,
9)
dix
11classe La fenêtre(QWidget):
12 def __init__(soi):
13 super().__init__()
14 soi.setWindowTitle("Exemple QFormLayout")
15 soi.redimensionner(270, 110)
16 # Créer une instance QHBoxLayout
17 disposition = QFormLayout()
18 # Ajouter des widgets à la mise en page
19 disposition.ajouter une rangée("Nom:", QLineEdit())
20 disposition.ajouter une rangée("Emploi:", QLineEdit())
21 emailLabel = QLabel("Email:")
22 disposition.ajouter une rangée(emailLabel, QLineEdit())
23 # Définir la mise en page sur la fenêtre de l'application
24 soi.setLayout(disposition)
25
26si __Nom__ == "__principale__":
27 app = QApplication(sys.argv)
28 la fenêtre = La fenêtre()
29 la fenêtre.montrer()
30 sys.sortie(app.exec_())
À la ligne 17, vous créez un QFormLayout
objet. Ensuite, aux lignes 19 à 22, vous ajoutez quelques lignes à la mise en page. Notez qu'aux lignes 19 et 20, vous utilisez la deuxième variante de la méthode, et à la ligne 22, vous utilisez la première variante, en passant un QLabel
objet comme premier argument de .ajouter une rangée()
.
Si vous exécutez ce code, vous obtiendrez la fenêtre suivante sur votre écran:

Avec un QFormLayout
, vous pouvez organiser vos widgets en deux colonnes. La première colonne contient des étiquettes qui demandent à l'utilisateur des informations. La deuxième colonne affiche des widgets qui permettent à l'utilisateur de saisir ou de modifier ces informations.
Imbrication de dispositions pour créer des interfaces graphiques complexes
Vous pouvez utiliser imbriqué mises en page pour créer des interfaces graphiques complexes qu’il serait difficile de créer à l’aide de l’un des gestionnaires de mise en page à usage général de PyQt. Pour ce faire, vous devez appeler .addLayout ()
sur un disposition extérieure. De cette façon, le disposition intérieure devient un enfant de la disposition extérieure.
Supposons que vous deviez créer une boîte de dialogue qui affiche une étiquette et une modification de ligne dans une mise en page de formulaire, et sous ces widgets, vous souhaitez placer plusieurs cases à cocher dans une mise en page verticale. Voici une maquette de ce à quoi votre boîte de dialogue devrait ressembler:

Le rectangle bleu représente votre disposition extérieure. Le rectangle vert est la mise en page du formulaire qui contiendra l'étiquette et l'édition de ligne. Le rectangle rouge est la disposition verticale pour contenir les cases à cocher des options. La disposition verte et la disposition rouge sont imbriquées dans la disposition bleue, qui est une disposition verticale.
Voici un exemple de création de cette mise en page à l'aide de PyQt:
1importer sys
2
3de PyQt5.QtWidgets importer (
4 QApplication,
5 QCheckBox,
6 QFormLayout,
sept QLineEdit,
8 QVBoxLayout,
9 QWidget,
dix)
11
12classe La fenêtre(QWidget):
13 def __init__(soi):
14 super().__init__()
15 soi.setWindowTitle("Exemple de dispositions imbriquées")
16 # Créer une mise en page externe
17 externalLayout = QVBoxLayout()
18 # Créer une mise en page de formulaire pour le libellé et l'édition de ligne
19 topLayout = QFormLayout()
20 # Ajouter une étiquette et une modification de ligne à la mise en page du formulaire
21 topLayout.ajouter une rangée("Du texte:", QLineEdit())
22 # Créer une mise en page pour les cases à cocher
23 optionsMise en page = QVBoxLayout()
24 # Ajoutez des cases à cocher à la mise en page
25 optionsMise en page.addWidget(QCheckBox("Option un"))
26 optionsMise en page.addWidget(QCheckBox("Option deux"))
27 optionsMise en page.addWidget(QCheckBox("Option trois"))
28 # Imbriquez les dispositions intérieures dans la disposition extérieure
29 externalLayout.addLayout(topLayout)
30 externalLayout.addLayout(optionsMise en page)
31 # Définir la disposition principale de la fenêtre
32 soi.setLayout(externalLayout)
33
34si __Nom__ == "__principale__":
35 app = QApplication(sys.argv)
36 la fenêtre = La fenêtre()
37 la fenêtre.montrer()
38 sys.sortie(app.exec_())
Voici ce que vous faites dans ce code:
- En ligne 17, vous créez la mise en page externe, ou de niveau supérieur, que vous utiliserez comme mise en page parente et comme mise en page principale de votre fenêtre. Dans ce cas, vous utilisez
QVBoxLayout
car vous souhaitez que vos widgets soient disposés verticalement sur votre formulaire. Dans votre maquette, il s'agit de la mise en page bleue. - En ligne 19, vous créez une mise en page de formulaire pour contenir une étiquette et une modification de ligne.
- En ligne 21, vous ajoutez les widgets requis à la mise en page. Cela équivaut à votre mise en page verte.
- En ligne 23, vous créez une disposition verticale pour contenir les cases à cocher.
- Aux lignes 25 à 27, vous ajoutez les cases à cocher requises. Ceci est votre mise en page rouge.
- Aux lignes 29 et 30, vous nidifiez
topLayout
etoptionsMise en page
sous leexternalLayout
.
C'est ça! Si vous exécutez l'application, une fenêtre semblable à celle-ci s'affiche:

Dans cette application, vous imbriquez deux mises en page différentes sous une mise en page externe pour créer une mise en page générale pour votre fenêtre. En haut de la fenêtre, vous utilisez une disposition horizontale pour placer une étiquette et une ligne d'édition. Ensuite, vous placez des cases à cocher en dessous de cela en utilisant une disposition verticale.
Utilisation de mises en page et de widgets multipages
Jusqu'à présent, vous avez vu comment utiliser des gestionnaires de mise en page traditionnels ou à usage général pour organiser les widgets dans les fenêtres de votre application. Ces gestionnaires de disposition organiseront les widgets sur un mise en page sur une seule page. En d'autres termes, votre interface graphique affichera toujours le même ensemble de widgets à l'utilisateur.
Parfois, vous devez créer une mise en page qui affiche un ensemble différent de widgets en réponse à certaines actions de l'utilisateur sur l'interface graphique. Par exemple, si vous créez une boîte de dialogue de préférences pour une application donnée, vous souhaiterez peut-être présenter à l'utilisateur un par tabulation, ou plusieurs pages, mise en page dans laquelle chaque onglet ou page contient un ensemble différent d'options étroitement liées. Chaque fois que l'utilisateur clique sur un onglet ou une page, l'application affiche un ensemble différent de widgets.
PyQt fournit une disposition intégrée appelée QStackedLayout
et quelques widgets pratiques comme QTabWidget
cela vous permettra de créer ce type de mise en page multipage. Les prochaines sections vous guideront à travers certains de ces outils.
Créer une pile de widgets
QStackedLayout
fournit un gestionnaire de mise en page qui vous permettra d'organiser vos widgets sur un empiler, les uns sur les autres. Dans ce type de mise en page, un seul widget est visible à la fois.
Pour remplir une mise en page empilée avec des widgets, vous devez appeler .addWidget ()
sur l'objet de mise en page. Cela ajoutera chaque widget à la fin de la liste interne des widgets de la mise en page. Vous pouvez également insérer ou supprimer un widget à une position donnée dans la liste des widgets en utilisant .insertWidget (index)
ou .removeWidget (widget)
, respectivement.
Chaque widget de la liste des widgets est affiché comme une page indépendante. Si vous souhaitez afficher plusieurs widgets sur une page, utilisez un QWidget
objet pour chaque page et définissez une disposition appropriée des widgets pour le widget de page. Si vous avez besoin d'obtenir le nombre total de widgets (pages) dans la mise en page, vous pouvez appeler .compter()
.
Un point important à garder à l'esprit lorsque vous travaillez avec QStackedLayout
objets est que vous devez fournir explicitement un mécanisme pour basculer entre les pages. Sinon, votre mise en page affichera toujours la même page à l'utilisateur. Pour basculer entre les pages, vous devez appeler .setCurrentIndex ()
sur l'objet de mise en page.
Voici un exemple qui montre comment utiliser une mise en page empilée avec une zone de liste déroulante pour basculer entre les pages:
1importer sys
2
3de PyQt5.QtWidgets importer (
4 QApplication,
5 QComboBox,
6 QFormLayout,
sept QLineEdit,
8 QStackedLayout,
9 QVBoxLayout,
dix QWidget,
11)
12
13classe La fenêtre(QWidget):
14 def __init__(soi):
15 super().__init__()
16 soi.setWindowTitle("Exemple de QStackedLayout")
17 # Créer une mise en page de premier niveau
18 disposition = QVBoxLayout()
19 soi.setLayout(disposition)
20 # Créez et connectez la liste déroulante pour basculer entre les pages
21 soi.pageCombo = QComboBox()
22 soi.pageCombo.Ajouter des articles([[[["Page 1", "Page 2"])
23 soi.pageCombo.activé.relier(soi.switchPage)
24 # Créer la mise en page empilée
25 soi.stackedLayout = QStackedLayout()
26 # Créer la première page
27 soi.Page 1 = QWidget()
28 soi.page1Mise en page = QFormLayout()
29 soi.page1Mise en page.ajouter une rangée("Nom:", QLineEdit())
30 soi.page1Mise en page.ajouter une rangée("Adresse:", QLineEdit())
31 soi.Page 1.setLayout(soi.page1Mise en page)
32 soi.stackedLayout.addWidget(soi.Page 1)
33 # Créer la deuxième page
34 soi.page 2 = QWidget()
35 soi.page2Mise en page = QFormLayout()
36 soi.page2Mise en page.ajouter une rangée("Emploi:", QLineEdit())
37 soi.page2Mise en page.ajouter une rangée("Département:", QLineEdit())
38 soi.page 2.setLayout(soi.page2Mise en page)
39 soi.stackedLayout.addWidget(soi.page 2)
40 # Ajouter la liste déroulante et la disposition empilée à la disposition de niveau supérieur
41 disposition.addWidget(soi.pageCombo)
42 disposition.addLayout(soi.stackedLayout)
43
44 def switchPage(soi):
45 soi.stackedLayout.setCurrentIndex(soi.pageCombo.currentIndex())
46
47if __name__ == "__main__":
48 app = QApplication(sys.argv)
49 la fenêtre = Window()
50 la fenêtre.montrer()
51 sys.exit(app.exec_())
On lines 21 to 23, you create a QComboBox
object that will allow you to switch between the pages in the layout. Then you add two options to the combo box in a list and connect it to .switchPage()
, which is intended to handle page switching.
Inside .switchPage()
, you call .setCurrentIndex()
on the layout object, passing the current index of the combo box as an argument. This way, when the user changes the option in the combo box, the page on the stacked layout will change accordingly.
On line 25, you create the QStackedLayout
object. On lines 27 to 32, you add the first page to the layout, and on lines 34 to 39, you add the second page. Each page is represented by a QWidget
object that contains several widgets in a convenient layout.
The final step to get everything working is to add the combo box and the layout to the application’s main layout.
Here’s how your application behaves now:

In this case, you have two pages in your application’s layout. Each page is represented by a QWidget
object. When you select a new page in the combo box on the top of the window, the layout changes to show the selected page.
Remarque: PyQt provides a convenient class called QStackedWidget
, which is built on top of QStackedLayout
. You can also use this class to create multipage layouts.
This class provides a stack of widgets in which only one widget is visible at a time. Just like stacked layouts, QStackedWidget
doesn’t provide an intrinsic mechanism for switching between pages.
Besides stacked layout and stacked widget, you can use QTabWidget
to create a multipage user interface. You’ll learn how in the next section.
Using PyQt’s Tab Widgets
Another popular way of creating multipage arrangements in PyQt is by using a class called QTabWidget
. This class provides a tab bar and a page area. You use the tab bar to switch between pages and the page area to display the page associated with the selected tab.
The tab bar is located at the top of the page area by default. However, you can change this behavior using .setTabPosition()
and one of four possible tab positions:
Tab Position | Tab Bar Location |
---|---|
QTabWidget.North |
Top of the pages |
QTabWidget.South |
Bottom of the pages |
QTabWidget.West |
Left of the pages |
QTabWidget.East |
Right of the pages |
To add tabs to a tab widget, you use .addTab()
. This method has two variations, or overloaded implementations:
.addTab(page, label)
.addTab(page, icon, label)
In both cases, the method adds a new tab, with label
as the tab’s title. page
needs to be a widget representing the page associated with the tab at hand.
In the second variation of the method, icon
needs to be a QIcon
object. If you pass an icon to .addTab()
, then that icon will be shown to the left of the tab’s title.
A common practice when creating tab widgets is to use a QWidget
object for each page. This way, you’ll be able to add extra widgets to the page using a layout containing the required widgets.
Most of the time, you’ll use tab widgets to create dialogs for your GUI applications. This kind of layout allows you to present the user with several options in a relatively small space. You can also take advantage of the tab system to organize your options according to some classification criteria.
Here’s a sample application that shows the basics of how to create and use a QTabWidget
object:
1import sys
2
3de PyQt5.QtWidgets import (
4 QApplication,
5 QCheckBox,
6 QTabWidget,
sept QVBoxLayout,
8 QWidget,
9)
dix
11class Window(QWidget):
12 def __init__(self):
13 super().__init__()
14 self.setWindowTitle("QTabWidget Example")
15 self.resize(270, 110)
16 # Create a top-level layout
17 layout = QVBoxLayout()
18 self.setLayout(layout)
19 # Create the tab widget with two tabs
20 tabs = QTabWidget()
21 tabs.addTab(self.generalTabUI(), "General")
22 tabs.addTab(self.networkTabUI(), "Network")
23 layout.addWidget(tabs)
24
25 def generalTabUI(self):
26 """Create the General page UI."""
27 generalTab = QWidget()
28 layout = QVBoxLayout()
29 layout.addWidget(QCheckBox("General Option 1"))
30 layout.addWidget(QCheckBox("General Option 2"))
31 generalTab.setLayout(layout)
32 return generalTab
33
34 def networkTabUI(self):
35 """Create the Network page UI."""
36 networkTab = QWidget()
37 layout = QVBoxLayout()
38 layout.addWidget(QCheckBox("Network Option 1"))
39 layout.addWidget(QCheckBox("Network Option 2"))
40 networkTab.setLayout(layout)
41 return networkTab
42
43if __name__ == "__main__":
44 app = QApplication(sys.argv)
45 la fenêtre = Window()
46 la fenêtre.montrer()
47 sys.exit(app.exec_())
In this example, you use a tab widget to present the user with a concise dialog that shows options related to the General et Network sections of a hypothetical preferences menu. On line 20, you create the QTabWidget
object. Then you add two tabs to the tab widget using .addTab()
.
Dans .generalTabUI()
et networkTabUI()
, you create the specific GUI for each tab. To do this, you use a QWidget
object, a QVBoxLayout
object, and some checkboxes to hold the options.
If you run the application now, then you’ll get the following dialog on your screen:

That’s it! You have a fully functional tab-based GUI. Note that to switch between pages, you just need to click the corresponding tab.
Laying Out the Application’s Main Window
If you’re using PyQt to create your GUI applications, then most of the time you’ll use QMainWindow
to create a GUI on top of it. This class allows you to create main window–style applications. QMainWindow
ships with its own predefined layout. This layout will allow you to add the following graphical components to your main window:
- A menu bar at the top of the window
- One or more toolbars at any of the four sides of the window
- A status bar at the bottom of the window
- One or more dock widgets at any of the four sides of the window (but without occupying the toolbars area)
- A central widget at the very center of the window
For most applications, all these graphical components are optional except for the central widget, which is required to make your application work.
Remarque: If you’re creating GUI applications using QMainWindow
, then you doit have a central widget, even if it’s just a placeholder.
Some applications use a unique and fully functional widget as their central widget. For example, if you’re coding a text editor, then you’ll likely use a QTextEdit
object as your editor’s central widget.
Other kinds of GUI applications might require a more elaborate central widget. In that case, you can use a QWidget
object as your central widget and then create a layout containing the specific widget arrangement that you need for your application’s GUI. The final step is to set that layout as your central widget’s layout.
Most of the time, the layout that QMainWindow
offers is enough to create any kind of GUI application. This layout will effectively manage the behavior of the widgets on the window, so you don’t have to worry about that.
Laying Out the Application’s Dialogs
GUI applications are commonly built using a main window and one or more dialogs. Dialogs are small windows that allow you to communicate with your users. PyQt provides QDialog
to handle the creation of dialogs.
Unlike QMainWindow
, QDialog
doesn’t have a predefined or default top-level layout. That’s because dialogs can be quite varied and include a wide range of widget arrangements and combinations.
Once you place all the widgets on a dialog’s GUI, you need to set a top-level layout on that dialog. To do this, you have to call .setLayout()
on the dialog object just like you’d do with any other widget.
Here’s a dialog-style application that shows how to set a top-level layout to a QDialog
object:
1import sys
2
3de PyQt5.QtWidgets import (
4 QApplication,
5 QDialog,
6 QDialogButtonBox,
sept QFormLayout,
8 QLineEdit,
9 QVBoxLayout,
dix)
11
12class Dialog(QDialog):
13 def __init__(self):
14 super().__init__()
15 self.setWindowTitle("QDialog's Top-Level Layout Example")
16 dlgLayout = QVBoxLayout()
17 # Create a form layout and add widgets
18 formLayout = QFormLayout()
19 formLayout.addRow("Name:", QLineEdit())
20 formLayout.addRow("Job:", QLineEdit())
21 formLayout.addRow("Email:", QLineEdit())
22 # Add a button box
23 btnBox = QDialogButtonBox()
24 btnBox.setStandardButtons(
25 QDialogButtonBox.D'accord | QDialogButtonBox.Cancel
26 )
27 # Set the layout on the dialog
28 dlgLayout.addLayout(formLayout)
29 dlgLayout.addWidget(btnBox)
30 self.setLayout(dlgLayout)
31
32if __name__ == "__main__":
33 app = QApplication(sys.argv)
34 dlg = Dialog()
35 dlg.montrer()
36 sys.exit(app.exec_())
In this case, the application’s window inherits from QDialog
, so you have a dialog-style application. On line 16, you create the layout that you’ll use as the dialog’s top-level layout. On lines 18 to 21, you create a form layout to arrange some widgets in a form.
On line 24, you add a QDialogButtonBox
object. You’ll often use QDialogButtonBox
to handle the buttons on a dialog. In this example, you use two buttons, an D'accord button and a Cancel bouton. These buttons won’t have any functionality—they’re just intended to make the dialog more realistic.
Once you have all the widgets and layouts in place, you can add them to the top-level layout. That’s what you do on lines 28 and 29. The final step, on line 30, is to set the top-level layout as your dialog’s layout using .setLayout()
.
If you run this application, then you’ll see the following window on your screen:

It’s a best practice to set a top-level layout for all your dialogs. This ensures that the dialog’s GUI will behave coherently when the user resizes the underlying window. Otherwise, your dialogs could appear disorganized and unpolished in the user’s eyes.
Managing Space in a PyQt Layout
When it comes to using PyQt’s layout managers to arrange the widgets on a window or form, managing space—empty space, space between widgets, and so on—is a common issue. Being able to manage this space is an important skill to have.
Internally, layouts manage the available space on a window using some of the following widget properties:
Layouts use these properties to automatically position and resize widgets, assigning a given amount of space to each widget according to the available space. This ensures that widgets are consistently arranged and remain usable.
In the next three sections, you’ll learn how the different types of layouts manage space in PyQt.
Managing Space in Box Layouts
Box layouts do a great job when it comes to distributing available space between widgets. However, sometime their default behavior isn’t enough, and you need to manually handle the available space. To help you out in this situation, PyQt provides QSpacerItem
. This class allows you to add blank space (or empty boxes) to a box layout.
Normally, you don’t need to use QSpacerItem
directement. Instead, you call some of the following methods on your box layout objects:
-
.addSpacing(i)
adds a non-stretchable space (or empty box) of fixed sizeje
to the layout.je
must be an integer representing the size of the space in pixels. -
.addStretch(i)
adds a stretchable space with a minimum size of0
and a stretch factorje
to a box layout.je
must be an integer. -
.insertSpacing(index, size)
inserts a non-stretchable space at positionindex
, with sizesize
. Siindex
is negative, then the space is added at the end of the box layout. -
insertStretch(index, stretch)
inserts a stretchable space at positionindex
, with a minimum size of0
and a stretch factor ofstretch
. Siindex
is negative, then the space is added at the end of the box layout.
Stretchable spacers will expand or shrink to fill empty space when the user resizes the underlying window. Non-stretchable spacers will remain the same size regardless of the changes in the size of the underlying window.
Go back to the example of how to use vertical layouts and run that application again. If you pull down the border of the window, then you’ll notice that more space appears between the buttons the further down you pull:

This happens because the layout handles the newly available space by automatically expanding its boxes. You can change this behavior by adding a stretchable QSpacerItem
object to the end of the layout.
In your example’s code, update the initializer of Window
as follows:
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QVBoxLayout Example")
self.resize(270, 110)
# Create a QVBoxLayout instance
layout = QVBoxLayout()
# Add widgets to the layout
layout.addWidget(QPushButton("Top"))
layout.addWidget(QPushButton("Center"))
layout.addWidget(QPushButton("Bottom"))
layout.addStretch()
# Set the layout on the application's window
self.setLayout(layout)
In the highlighted line, you add a stretchable QSpacerItem
object to the end of the layout by calling .addStretch()
on the layout. If you run the application again, then you’ll get the following behavior:

Now all the extra space is automatically assigned to the stretchable QSpacerItem
object at the bottom of the layout without affecting the position or size of the rest of the widgets. You can use this and other space management techniques to make your GUI applications look good and polished.
Managing Space in Grid and Form Layouts
Grid and form layouts handle available space in a different way. In these types of layouts, you can handle only the vertical and horizontal space between widgets. These layouts provide three methods to manage these spaces:
setSpacing(spacing)
sets both the vertical and the horizontal spacing between widgets tospacing
.setVerticalSpacing(spacing)
sets only the vertical spacing between widgets in the layout tospacing
.setHorizontalSpacing(spacing)
sets only the horizontal spacing between widgets in the layout tospacing
.
In all cases, spacing
is an integer representing pixels. Now go back to the example on how to create a form layout and update the initializer of Window
like this:
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QFormLayout Example")
self.resize(270, 110)
# Create a QHBoxLayout instance
layout = QFormLayout()
# Add widgets to the layout
layout.setVerticalSpacing(30)
layout.addRow("Name:", QLineEdit())
layout.addRow("Job:", QLineEdit())
emailLabel = QLabel("Email:")
layout.addRow(emailLabel, QLineEdit())
# Set the layout on the application's window
self.setLayout(layout)
In the highlighted line, you set the vertical space between widgets to 30
pixels. If you run the application again, then you’ll see the following window:

Now there’s more space between the rows of widgets. You can also try modifying the example of how to use a grid layout by adding some vertical or horizontal space just to see how all these spacing mechanisms work.
Conclusion
Creating high-quality GUI applications requires laying out all the graphical components in a coherent and polished arrangement. In PyQt, an effective way of doing that is to use PyQt’s layout managers, which provide a user-friendly and productive way of approaching this task.
In this tutorial, you’ve learned:
- What the benefits are of properly laying out the widgets on a GUI
- How to programmatically arrange widgets using PyQt’s built-in layout managers
- Which layout manager to use for your specific use case
- How to lay out main window–style et dialog-style applications in PyQt
With this knowledge, you’ll be able to create good-looking and professional GUI applications using PyQt’s built-in layouts.