Accès rapide :
Présentation de la stratégie de positionnement
Utilisation de la méthode pack pour les zones latérales
Possibilité de placer plusieurs widgets sur une zone latérale
Occupation de la zone centrale
Nous poursuivons notre étude des stratégies de positionnement proposées par Tkinter et nous allons maintenant parler de la stratégie
pack
. Cette stratégie de positionnement
permet de positionner vos widgets dans 5 zones de votre conteneur : la zone centrale et les zones périphériques en haut, en bas,
à gauche et à droite. La capture d'écran suivante montre un exemple d'utilisation.
Ce découpage est très courant pour une interface graphique. Classiquement, dans la zone supérieure, on peut y retrouver une barre d'outils. En bas, il n'est pas rare d'avoir une barre de statuts. Sur les zones à gauche et à droite, on peut retrouver des arborescences (pensez à un explorateur de fichiers). Et, en général, on retrouve un éditeur dans la zone centrale.
Pour positionner un widget dans l'une des zones latérales d'un conteneur (dans notre cas, la fenêtre), il faut invoquer la méthode
pack
et préciser le côté dans lequel placer le widget.
pack
est disponible sur n'importe quel widget.
Mais en réalité, c'est la classe Pack
qui porte cette méthode
et par le jeu subtil de l'héritage cette méthode est transmise à toutes les classes de widgets.
Voici un premier exemple simple d'utilisation.
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 27 28 29 30 31 32 33 34 35 36 37 38 |
#!/usr/bin/python3 from tkinter import Tk, Label # On définit une classe qui dérive de la classe Tk (la classe de fenêtre). class MyWindow(Tk): def __init__(self): # On appelle le constructeur parent super().__init__() # On positionne un premier label en haut first_label = Label(self, text="side='top'", fg="white", bg="#FF00FF") first_label.pack(side="top") # On positionne un second label en bas second_label = Label(self, text="side='bottom'", fg="white", bg="green") second_label.pack(side="bottom") # On positionne un troisième label à gauche third_label = Label(self, text="side='left'", fg="white", bg="red") third_label.pack(side="left") # On positionne un quatrième label à droite fourth_label = Label(self, text="side='right'", fg="white", bg="orange") fourth_label.pack(side="right") # On dimensionne la fenêtre (500 pixels de large par 200 de haut). self.geometry("500x200") # On ajoute un titre à la fenêtre self.title("Positionnement de widgets via pack") # On crée notre fenêtre et on l'affiche window = MyWindow() window.mainloop() |
Et voici le résultat affiché par cet exemple de code Tkinter.
Comme vous le constatez, les labels sont bien placés dans les zones latérales, mais ils n'occupent pas tout l'espace de chaque zone.
Vous pouvez changer cela en utilisant le paramètre fill
: il accepte les valeurs "x"
, "y"
et
"both"
. Modifions notre code pour occuper tout l'espace de chaque zone latérale.
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 27 28 29 30 31 32 33 34 35 36 37 38 |
#!/usr/bin/python3 from tkinter import Tk, Label # On définit une classe qui dérive de la classe Tk (la classe de fenêtre). class MyWindow(Tk): def __init__(self): # On appelle le constructeur parent super().__init__() # On positionne un premier label en haut first_label = Label(self, text="side='top'", fg="white", bg="#FF00FF") first_label.pack(side="top", fill='x') # On positionne un second label en bas second_label = Label(self, text="side='bottom'", fg="white", bg="green") second_label.pack(side="bottom", fill='x') # On positionne un troisième label à gauche third_label = Label(self, text="side='left'", fg="white", bg="red") third_label.pack(side="left", fill='y') # On positionne un quatrième label à droite fourth_label = Label(self, text="side='right'", fg="white", bg="orange") fourth_label.pack(side="right", fill='y') # On dimensionne la fenêtre (500 pixels de large par 200 de haut). self.geometry("500x200") # On ajoute un titre à la fenêtre self.title("Positionnement de widgets via pack") # On crée notre fenêtre et on l'affiche window = MyWindow() window.mainloop() |
Et voici le résultat produit par l'exemple ci-dessus.
Tout est dit dans le titre : on peut placer plusieurs widgets dans une zone latérale. Dans l'exemple ci-dessous, deux labels sont placés au « top » de la fenêtre.
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 27 28 29 30 31 32 33 34 35 36 37 38 |
#!/usr/bin/python3 from tkinter import Tk, Label # On définit une classe qui dérive de la classe Tk (la classe de fenêtre). class MyWindow(Tk): def __init__(self): # On appelle le constructeur parent super().__init__() # On positionne un premier label en haut first_label = Label(self, text="side='top'", fg="white", bg="#FF00FF") first_label.pack(side="top", fill='x') # On positionne un second label en haut second_label = Label(self, text="side='top'", fg="white", bg="green") second_label.pack(side="top", fill='x') # On positionne un troisième label à gauche third_label = Label(self, text="side='left'", fg="white", bg="red") third_label.pack(side="left", fill='y') # On positionne un quatrième label à droite fourth_label = Label(self, text="side='right'", fg="white", bg="orange") fourth_label.pack(side="right", fill='y') # On dimensionne la fenêtre (500 pixels de large par 200 de haut). self.geometry("500x200") # On ajoute un titre à la fenêtre self.title("Positionnement de widgets via pack") # On crée notre fenêtre et on l'affiche window = MyWindow() window.mainloop() |
Et voici le résultat produit par l'exemple ci-dessus.
Notez que l'ordre d'ajout dans le conteneur est très importante. Voici un nouvel exemple pour illustrer mon propos.
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 27 28 29 30 31 32 33 34 35 36 37 38 |
#!/usr/bin/python3 from tkinter import Tk, Label # On définit une classe qui dérive de la classe Tk (la classe de fenêtre). class MyWindow(Tk): def __init__(self): # On appelle le constructeur parent super().__init__() # On positionne un premier label en haut first_label = Label(self, text="side='top'", fg="white", bg="#FF00FF") first_label.pack(side="top", fill='x') # On positionne un second label à gauche second_label = Label(self, text="side='left'", fg="white", bg="red") second_label.pack(side="left", fill='y') # On positionne un troisième label à droite third_label = Label(self, text="side='right'", fg="white", bg="orange") third_label.pack(side="right", fill='y') # On ajoute un dernier label en haut fourth_label = Label(self, text="side='top'", fg="white", bg="green") fourth_label.pack(side="top", fill='x') # On dimensionne la fenêtre (500 pixels de large par 200 de haut). self.geometry("500x200") # On ajoute un titre à la fenêtre self.title("Positionnement de widgets via pack") # On crée notre fenêtre et on l'affiche window = MyWindow() window.mainloop() |
Dans l'exemple ci-dessus, le deuxième widget du haut est ajouté après avoir injecté les widgets des zones gauche et droite. Le dernier label n'occupera donc pas toute la largeur de la fenêtre. Voici une capture d'écran.
Pour placer un widget dans la zone centrale, il suffit de ne pas spécifier le paramètre side
.
Mais attention, par défaut les widgets seront dimensionnés au plus juste par rapport à leur contenu et ils s'afficheront les uns en dessous des autres.
Voici un exemple injectant deux boutons dans la zone centrale.
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 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#!/usr/bin/python3 from tkinter import Tk, Label, Button # On définit une classe qui dérive de la classe Tk (la classe de fenêtre). class MyWindow(Tk): def __init__(self): # On appelle le constructeur parent super().__init__() # On positionne quatre labels sur les quatre côtés first_label = Label(self, text="side='top'", fg="white", bg="#FF00FF") first_label.pack(side="top", fill='x') second_label = Label(self, text="side='bottom'", fg="white", bg="green") second_label.pack(side="bottom", fill='x') third_label = Label(self, text="side='left'", fg="white", bg="red") third_label.pack(side="left", fill='y') fourth_label = Label(self, text="side='right'", fg="white", bg="orange") fourth_label.pack(side="right", fill='y') # On ajoute deux boutons dans la zone centrale. # Les textes des deux boutons sont volontairement de tailles différentes button1 = Button(self, text="Click me, please!", fg="white", bg="blue") button1.pack() button2 = Button(self, text="Veuillez, s'il vous plait, me cliquer dessus !", fg="white", bg="blue") button2.pack() # On dimensionne la fenêtre (500 pixels de large par 200 de haut). self.geometry("500x200") # On ajoute un titre à la fenêtre self.title("Positionnement de widgets via pack") # On crée notre fenêtre et on l'affiche window = MyWindow() window.mainloop() |
Et voici le résultat produit par cet exemple.
Mais, peut-être, auriez-vous préféré qu'il n'y ait qu'un seul widget centrale (pourquoi un
Frame
) et qu'il soit centré dans cette zone.
Dans ce cas, il faut fixer le paramètre expand
à la valeur 1 et votre widget sera centré dans la fenêtre.
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 27 28 29 30 31 32 33 34 35 36 |
#!/usr/bin/python3 from tkinter import Tk, Label, Button # On définit une classe qui dérive de la classe Tk (la classe de fenêtre). class MyWindow(Tk): def __init__(self): # On appelle le constructeur parent super().__init__() # On positionne quatre labels sur les quatre côtés first_label = Label(self, text="side='top'", fg="white", bg="#FF00FF") first_label.pack(side="top", fill='x') second_label = Label(self, text="side='bottom'", fg="white", bg="green") second_label.pack(side="bottom", fill='x') third_label = Label(self, text="side='left'", fg="white", bg="red") third_label.pack(side="left", fill='y') fourth_label = Label(self, text="side='right'", fg="white", bg="orange") fourth_label.pack(side="right", fill='y') # On ajoute un boutona dans la zone centrale. button1 = Button(self, text="Click me!", fg="white", bg="blue") button1.pack(expand=1) # On dimensionne la fenêtre (500 pixels de large par 200 de haut). self.geometry("500x200") # On ajoute un titre à la fenêtre self.title("Positionnement de widgets via pack") # On crée notre fenêtre et on l'affiche window = MyWindow() window.mainloop() |
Voici le résultat produit par cet exemple.
Enfin, si vous souhaitez qu'il occupe toute la zone centrale, il faut rajouter le paramètre fill
fixé à la valeur "both"
.
Voici un dernier exemple de code pour cette stratégie.
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 27 28 29 30 31 32 33 34 35 36 |
#!/usr/bin/python3 from tkinter import Tk, Label, Button # On définit une classe qui dérive de la classe Tk (la classe de fenêtre). class MyWindow(Tk): def __init__(self): # On appelle le constructeur parent super().__init__() # On positionne quatre labels sur les quatre côtés first_label = Label(self, text="side='top'", fg="white", bg="#FF00FF") first_label.pack(side="top", fill='x') second_label = Label(self, text="side='bottom'", fg="white", bg="green") second_label.pack(side="bottom", fill='x') third_label = Label(self, text="side='left'", fg="white", bg="red") third_label.pack(side="left", fill='y') fourth_label = Label(self, text="side='right'", fg="white", bg="orange") fourth_label.pack(side="right", fill='y') # On ajoute un bouton dans la zone centrale. button1 = Button(self, text="Click me!", fg="white", bg="blue") button1.pack(expand=1, fill="both") # On dimensionne la fenêtre (500 pixels de large par 200 de haut). self.geometry("500x200") # On ajoute un titre à la fenêtre self.title("Positionnement de widgets via pack") # On crée notre fenêtre et on l'affiche window = MyWindow() window.mainloop() |
Et voici le résultat produit par ce dernier exemple.
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :