Tkinter grid - créer une interface Python responsive

Noël Besnard .

13 octobre 2026

Interface calculatrice simple créée avec tkinter grid. Le code Python affiche la logique de la calculatrice.

Une fenêtre Tkinter peut vite devenir difficile à maintenir dès que les champs, boutons et messages doivent rester alignés lorsque l’utilisateur redimensionne l’interface. Le gestionnaire tkinter grid répond précisément à ce besoin en organisant les widgets dans des lignes et des colonnes. Je vais montrer comment le mettre en place, le rendre responsive, gérer les espacements et éviter les erreurs qui produisent des interfaces déséquilibrées.

Les principes essentiels pour construire une interface Tkinter équilibrée

  • grid() place les widgets dans des cellules organisées par lignes et colonnes.
  • sticky="nsew" permet à un widget de s’étirer dans sa cellule.
  • weight=1 indique quelles lignes et colonnes absorbent l’espace supplémentaire.
  • rowspan et columnspan permettent de fusionner plusieurs cellules.
  • Il ne faut pas mélanger pack() et grid() dans un même conteneur.

Comprendre le gestionnaire tkinter grid

La méthode grid() place chaque widget dans une cellule définie par une ligne et une colonne. Les indices commencent à zéro, ce qui signifie que la première cellule correspond à row=0 et column=0.

import tkinter as tk

fenetre = tk.Tk()
fenetre.title("Formulaire")

tk.Label(fenetre, text="Nom").grid(row=0, column=0)
tk.Entry(fenetre).grid(row=0, column=1)

tk.Label(fenetre, text="E-mail").grid(row=1, column=0)
tk.Entry(fenetre).grid(row=1, column=1)

fenetre.mainloop()

Ce fonctionnement est particulièrement adapté aux formulaires, aux tableaux de paramètres et aux fenêtres de configuration. Contrairement à pack(), qui empile les widgets autour des bords, la grille donne un contrôle direct sur leur position relative.

Je recommande de réserver chaque grille à un conteneur clair, souvent une instance de Frame. Cette organisation évite les mises en page difficiles à modifier lorsque l’application grandit.

Les options qui comptent vraiment

Option Rôle Exemple
row Définit la ligne du widget row=0
column Définit la colonne du widget column=1
padx et pady Ajoutent un espace extérieur padx=8
ipadx et ipady Ajoutent un espace intérieur ipady=4
rowspan et columnspan Étendent un widget sur plusieurs cellules columnspan=2

Faire réagir la fenêtre avec sticky et weight

Une grille correctement positionnée peut tout de même sembler figée si ses colonnes ne savent pas utiliser l’espace disponible. Deux réglages font presque toute la différence : sticky contrôle l’alignement du widget, tandis que weight détermine comment l’espace supplémentaire est distribué.

Les lettres de sticky correspondent aux directions cardinales. Ainsi, "w" aligne le widget à gauche, "e" à droite et "nsew" l’étire dans les quatre directions.

import tkinter as tk

fenetre = tk.Tk()
fenetre.geometry("500x220")

fenetre.columnconfigure(1, weight=1)
fenetre.rowconfigure(1, weight=1)

tk.Label(fenetre, text="Adresse").grid(
    row=0, column=0, padx=10, pady=10, sticky="w"
)

champ = tk.Entry(fenetre)
champ.grid(row=0, column=1, padx=10, pady=10, sticky="ew")

zone = tk.Text(fenetre)
zone.grid(row=1, column=0, columnspan=2, padx=10, pady=10, sticky="nsew")

fenetre.mainloop()

La colonne 1 reçoit ici un poids de 1 et peut donc s’élargir. La ligne 1 fonctionne de la même manière pour la zone de texte. Sans ces deux instructions, la fenêtre pourrait s’agrandir, mais les widgets resteraient concentrés dans leur taille minimale, ce qui donne souvent une impression de vide.

Un poids de 2 reçoit environ deux fois plus d’espace supplémentaire qu’un poids de 1. Pour deux colonnes de largeur équivalente, attribuez-leur le même poids, par exemple weight=1 sur chacune.

Construire un formulaire propre avec Frame

Pour une interface réaliste, je préfère séparer la fenêtre en zones fonctionnelles. Un Frame peut contenir le formulaire, un autre les boutons d’action et un troisième un message d’état. Chaque conteneur possède alors sa propre grille, ce qui rend le code plus lisible.

import tkinter as tk
from tkinter import ttk

fenetre = tk.Tk()
fenetre.title("Création de compte")
fenetre.geometry("420x230")

formulaire = ttk.Frame(fenetre, padding=16)
formulaire.grid(row=0, column=0, sticky="nsew")

fenetre.columnconfigure(0, weight=1)
fenetre.rowconfigure(0, weight=1)

formulaire.columnconfigure(1, weight=1)

ttk.Label(formulaire, text="Nom").grid(
    row=0, column=0, padx=6, pady=6, sticky="w"
)
ttk.Entry(formulaire).grid(
    row=0, column=1, padx=6, pady=6, sticky="ew"
)

ttk.Label(formulaire, text="Mot de passe").grid(
    row=1, column=0, padx=6, pady=6, sticky="w"
)
ttk.Entry(formulaire, show="*").grid(
    row=1, column=1, padx=6, pady=6, sticky="ew"
)

boutons = ttk.Frame(formulaire)
boutons.grid(row=2, column=0, columnspan=2, pady=(14, 0))

ttk.Button(boutons, text="Annuler").grid(row=0, column=0, padx=4)
ttk.Button(boutons, text="Valider").grid(row=0, column=1, padx=4)

fenetre.mainloop()

Le point important est que le poids doit être configuré dans le parent qui gère la grille. Dans cet exemple, c’est formulaire qui doit rendre la colonne 1 extensible, et non le champ Entry lui-même.

Les espaces extérieurs avec padx et pady améliorent souvent davantage le résultat que l’ajout de couleurs ou de bordures. Je conseille de commencer avec une valeur comprise entre 6 et 16 pixels, puis d’ajuster selon la densité de l’interface.

Fusionner des cellules et aligner plusieurs widgets

Les options columnspan et rowspan servent lorsqu’un élément doit occuper plusieurs cellules. Un titre peut ainsi traverser toute la largeur d’un formulaire, tandis qu’une grande zone de texte peut prendre plusieurs lignes.

titre = ttk.Label(
    formulaire,
    text="Informations personnelles",
    font=("Arial", 14, "bold")
)
titre.grid(row=0, column=0, columnspan=2, pady=(0, 12))

ttk.Label(formulaire, text="Prénom").grid(
    row=1, column=0, sticky="w"
)
ttk.Entry(formulaire).grid(
    row=1, column=1, sticky="ew"
)

Pour des colonnes qui doivent conserver la même largeur malgré des contenus différents, la configuration uniform peut être utile. Elle est moins fréquente dans les petits scripts, mais elle devient intéressante pour des panneaux de boutons ou des tableaux de commandes réguliers.

Un autre détail souvent négligé concerne l’alignement des étiquettes. Utiliser sticky="w" pour les textes placés à gauche donne une ligne visuelle nette. Sans cette option, les labels peuvent sembler centrés dans leurs cellules et rendre le formulaire moins naturel.

Éviter les erreurs classiques avec grid

Ne pas mélanger pack et grid dans le même parent

Tkinter permet d’utiliser pack(), grid() et place(), mais un même conteneur ne doit pas être géré simultanément par pack et grid. Cette erreur déclenche généralement un message TclError et bloque l’affichage.

cadre = ttk.Frame(fenetre)
cadre.grid(row=0, column=0)

# Correct
ttk.Label(cadre, text="Nom").grid(row=0, column=0)
ttk.Entry(cadre).grid(row=0, column=1)

Le mélange reste possible dans des conteneurs différents. Par exemple, la fenêtre principale peut utiliser pack() pour empiler plusieurs cadres, tandis que chaque cadre utilise sa propre grille interne. C’est même une stratégie pratique pour les interfaces complexes.

Vérifier le parent réel du widget

Un widget doit être placé dans la grille de son parent direct. Si un champ appartient à formulaire, configurez les lignes et colonnes de formulaire, pas celles de la fenêtre principale. Cette confusion explique une grande partie des layouts qui refusent de s’étirer.

Lire aussi : Python str.replace - Maîtrisez le remplacement de sous-chaînes

Utiliser les outils de diagnostic

Quand un widget disparaît ou se retrouve au mauvais endroit, inspectez sa position avec grid_info(). Les méthodes grid_size(), grid_slaves() et grid_forget() sont également utiles pour comprendre la structure en cours d’exécution.

print(champ.grid_info())
print(formulaire.grid_size())
print(formulaire.grid_slaves())

Je vérifie aussi les dimensions de la fenêtre avant de modifier le code. Un widget mal visible n’est pas toujours mal positionné : il peut simplement être trop petit, masqué par un autre élément ou placé dans une ligne sans poids.

Choisir entre grid, pack et place

Le choix du gestionnaire dépend surtout de la structure souhaitée. Pour une décision rapide, cette comparaison suffit dans la plupart des projets Python.

Gestionnaire Usage recommandé Limite principale
grid Formulaires, tableaux, interfaces redimensionnables Demande une configuration des lignes et colonnes
pack Empilement simple de cadres ou de boutons Moins précis pour les alignements en deux dimensions
place Positionnement fixe ou effets très spécifiques Résiste mal aux changements de taille et de police

Pour une fenêtre composée de champs alignés, je choisis presque toujours grid. Pour une barre horizontale de boutons, pack() peut être plus rapide. Quant à place(), je le réserve aux cas où la position en pixels est réellement voulue, car il devient fragile dès que l’interface doit s’adapter.

La méthode la plus fiable pour une grille responsive

Une mise en page solide suit généralement quatre règles simples. Je les applique dès le début, car corriger une grille devenue complexe coûte beaucoup plus de temps que la préparer correctement.

  • Créer un Frame par zone fonctionnelle.
  • Configurer weight=1 sur les lignes et colonnes qui doivent grandir.
  • Utiliser sticky="ew" pour les champs horizontaux et sticky="nsew" pour les zones extensibles.
  • Conserver des espacements réguliers avec padx et pady.

Testez ensuite la fenêtre avec trois tailles différentes, par exemple 300, 500 et 800 pixels de largeur. Si les champs restent lisibles, que les boutons ne se chevauchent pas et que l’espace est réparti de manière logique, la base est saine.

La grille ne remplace pas une réflexion sur l’ergonomie. Elle fournit un système précis pour distribuer l’espace, mais c’est la hiérarchie des informations, la taille des textes et la cohérence des marges qui donnent à l’application son confort d’utilisation.

Ce que votre grille Tkinter doit réussir avant la mise en production

Une bonne interface ne se contente pas d’afficher les widgets au bon endroit. Elle doit rester compréhensible lorsque la fenêtre change de taille, lorsqu’un texte devient plus long ou lorsqu’un champ reçoit une valeur inattendue.

Commencez avec une structure simple, utilisez des cadres pour isoler les responsabilités et vérifiez systématiquement les couples weight et sticky. Cette combinaison résout la majorité des problèmes de redimensionnement rencontrés avec Tkinter.

Si une grille devient trop difficile à lire, ce n’est généralement pas un signe qu’il faut abandonner Tkinter. C’est souvent le moment de découper l’interface en plusieurs Frame indépendants, chacun avec une mise en page courte, prévisible et facile à tester.

Questions fréquentes

Utilisez sticky="ew" pour étirer un champ horizontalement et sticky="nsew" pour l’étendre dans toutes les directions. Configurez ensuite le parent direct avec columnconfigure(..., weight=1) ou rowconfigure(..., weight=1) afin qu’il distribue l’espace supplémentaire.
columnspan permet à un widget d’occuper plusieurs colonnes, par exemple un titre sur toute la largeur d’un formulaire. rowspan étend un widget sur plusieurs lignes, ce qui convient notamment aux grandes zones de texte ou aux panneaux qui doivent couvrir plusieurs cellules.
Tkinter ne doit pas gérer les widgets d’un même parent avec pack() et grid() simultanément, car cela provoque généralement une erreur TclError. En revanche, vous pouvez utiliser pack() dans la fenêtre principale et grid() à l’intérieur de cadres distincts.
grid est adapté aux formulaires, tableaux et interfaces redimensionnables. pack convient à l’empilement simple de cadres ou de boutons, tandis que place est réservé aux positionnements fixes, car il s’adapte mal aux changements de taille et de police.
Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

tkinter grille frame formulaires redimensionnement
Autor Noël Besnard
Noël Besnard
Je m'appelle Noël Besnard et je possède 7 ans d'expérience dans le domaine de la technologie, en particulier en ce qui concerne le web, l'intelligence artificielle, les réseaux et la sécurité. Mon intérêt pour ces sujets a commencé dès mon adolescence, lorsque j'ai découvert le potentiel incroyable des nouvelles technologies pour transformer notre quotidien. J'aime explorer les défis que posent ces avancées et partager des solutions accessibles pour aider les lecteurs à mieux comprendre ces enjeux. Au fil des ans, j'ai eu l'occasion d'écrire sur divers aspects de la tech, en mettant l'accent sur la clarté et la précision. Je m'efforce de vérifier mes sources et de comparer les informations afin de proposer un contenu à jour et fiable. Mon objectif est de rendre des sujets complexes plus simples et compréhensibles, tout en suivant les dernières tendances du secteur. Je suis ravi de partager mes connaissances et d'accompagner les lecteurs dans leur exploration des technologies qui façonnent notre avenir.
Commentaires (0)
Ajouter un commentaire