logo oujood
🔍

Le widget Frame Tkinter

Frame est le conteneur de base de Tkinter. Sans lui, organiser une interface un peu complexe devient vite ingérable.

OUJOOD.COM

Quand une interface contient plus de trois ou quatre widgets, les placer tous directement dans la fenêtre principale devient difficile à maintenir. Le widget Frame résout ce problème : c'est une zone rectangulaire qui regroupe des widgets et peut elle-même être positionnée dans la fenêtre. Pensez-y comme à des calques dans une mise en page.

Créer un Frame simple

Un Frame se crée comme n'importe quel widget — en lui passant son parent en premier argument :

📋 Copier le code

import tkinter as tk

fenetre = tk.Tk()
fenetre.title("Frame simple")
fenetre.geometry("400x250")

# Création d'un Frame avec bordure visible
cadre = tk.Frame(fenetre, bg="lightblue", bd=2, relief="groove")
cadre.pack(padx=20, pady=20, fill="both", expand=True)

# Les widgets suivants appartiennent au cadre, pas à la fenêtre
tk.Label(cadre, text="Je suis dans le Frame", bg="lightblue").pack(pady=10)
tk.Button(cadre, text="Bouton interne").pack()

fenetre.mainloop()

L'argument relief accepte plusieurs valeurs : "flat" (aucune bordure, défaut), "groove", "ridge", "sunken", "raised". C'est utile pour visualiser les zones lors du développement, même si on les retire souvent dans la version finale.

Diviser l'interface en zones

Le cas d'usage le plus courant : séparer l'interface en zones fonctionnelles — une barre du haut, une zone centrale, une barre du bas. Chaque zone est un Frame :

📋 Copier le code

import tkinter as tk

fenetre = tk.Tk()
fenetre.title("Interface en zones")
fenetre.geometry("450x300")

# Zone haute — barre de titre ou menu
frame_haut = tk.Frame(fenetre, bg="#3c3f41", height=50)
frame_haut.pack(fill="x")
tk.Label(frame_haut, text="Barre supérieure", bg="#3c3f41", fg="white").pack(pady=12)

# Zone centrale — contenu principal
frame_centre = tk.Frame(fenetre, bg="#f5f5f5")
frame_centre.pack(fill="both", expand=True, padx=10, pady=10)
tk.Label(frame_centre, text="Zone de contenu", bg="#f5f5f5").pack(pady=30)

# Zone basse — boutons d'action
frame_bas = tk.Frame(fenetre, bg="#e0e0e0", height=45)
frame_bas.pack(fill="x")
tk.Button(frame_bas, text="Annuler").pack(side="right", padx=5, pady=8)
tk.Button(frame_bas, text="Valider").pack(side="right", padx=5, pady=8)

fenetre.mainloop()

Chaque Frame utilise pack() avec fill="x" pour occuper toute la largeur. Le frame_centre a expand=True en plus, ce qui lui permet de prendre tout l'espace vertical disponible quand la fenêtre est redimensionnée.

Frames imbriqués

Un Frame peut contenir d'autres Frame. C'est ce qui permet de construire des mises en page complexes sans que tout s'effondre dès qu'un widget change de taille :

📋 Copier le code

import tkinter as tk

fenetre = tk.Tk()
fenetre.geometry("400x200")

# Frame parent
frame_principal = tk.Frame(fenetre, bg="#ddd")
frame_principal.pack(fill="both", expand=True, padx=10, pady=10)

# Deux colonnes à l'intérieur du frame principal
col_gauche = tk.Frame(frame_principal, bg="#c8e6c9", width=180)
col_gauche.pack(side="left", fill="both", expand=True, padx=(0, 5))

col_droite = tk.Frame(frame_principal, bg="#bbdefb", width=180)
col_droite.pack(side="left", fill="both", expand=True)

tk.Label(col_gauche, text="Colonne gauche", bg="#c8e6c9").pack(pady=20)
tk.Label(col_droite, text="Colonne droite", bg="#bbdefb").pack(pady=20)

fenetre.mainloop()

Ce type de structure en colonnes est la base de beaucoup d'interfaces réelles. Vous retrouverez ce schéma dans les exemples de la calculatrice et du gestionnaire de tâches en fin de cours.

Frame et gestionnaires de mise en page

Un point à ne pas oublier : dans un même Frame, vous ne pouvez pas mélanger pack() et grid(). Les deux gestionnaires sont incompatibles à l'intérieur d'un même conteneur. En revanche, un Frame peut utiliser grid() dans la fenêtre principale pendant que ses enfants utilisent pack() — les règles s'appliquent par conteneur, pas globalement. On approfondit ça dans les pages pack(), grid() et comment choisir entre eux.

Par carabde | Mis à jour le 30 avril 2025