logo oujood
🔍

Le widget Scrollbar Tkinter

Scrollbar ne défile pas seule — elle se connecte à un autre widget. Voici comment raccorder les deux correctement et éviter les erreurs classiques.

OUJOOD.COM

Le widget Scrollbar n'est pas autonome : il ne fait que transmettre des commandes de défilement à un autre widget. Sans cette connexion bidirectionnelle, la barre apparaît mais ne fait rien. C'est le point que la plupart des débutants ratent la première fois.

Principe de connexion

La liaison entre une Scrollbar et un widget défilable (Text, Listbox, Canvas) repose sur deux paramètres :

Le widget défilable reçoit yscrollcommand=scrollbar.set — il informe la scrollbar de sa position actuelle. La scrollbar reçoit command=widget.yview — elle transmet les clics et glissements au widget. Les deux sens sont nécessaires.

Scrollbar verticale avec Text

Le cas le plus courant — déjà évoqué dans la page sur le widget Text, développé ici plus en détail :

📋 Copier le code

import tkinter as tk

fenetre = tk.Tk()
fenetre.title("Scrollbar + Text")
fenetre.geometry("440x260")

frame = tk.Frame(fenetre)
frame.pack(fill="both", expand=True, padx=10, pady=10)

# Scrollbar créée en premier — elle sera passée à Text
scrollbar = tk.Scrollbar(frame, orient="vertical")
scrollbar.pack(side="right", fill="y")

zone_texte = tk.Text(
    frame,
    width=50,
    height=10,
    yscrollcommand=scrollbar.set  # Text informe la scrollbar
)
zone_texte.pack(side="left", fill="both", expand=True)

scrollbar.config(command=zone_texte.yview)  # Scrollbar commande le Text

for i in range(1, 40):
    zone_texte.insert(tk.END, f"Ligne {i} — texte de démonstration\n")

fenetre.mainloop()

L'ordre de création importe peu, mais l'ordre de pack() oui : la scrollbar doit être packée avant le widget principal avec side="right", sinon elle se retrouve en dessous. C'est un comportement de pack() à connaître.

Scrollbar verticale avec Listbox

Le raccordement avec Listbox suit exactement le même schéma :

📋 Copier le code

import tkinter as tk

fenetre = tk.Tk()
fenetre.title("Scrollbar + Listbox")
fenetre.geometry("300x220")

frame = tk.Frame(fenetre)
frame.pack(padx=10, pady=10)

scrollbar = tk.Scrollbar(frame, orient="vertical")
scrollbar.pack(side="right", fill="y")

liste = tk.Listbox(frame, height=8, yscrollcommand=scrollbar.set)
liste.pack(side="left")

scrollbar.config(command=liste.yview)

villes = ["Paris", "Lyon", "Marseille", "Toulouse", "Nice",
          "Nantes", "Strasbourg", "Bordeaux", "Lille", "Rennes",
          "Reims", "Saint-Étienne", "Toulon", "Grenoble", "Dijon"]

for ville in villes:
    liste.insert(tk.END, ville)

fenetre.mainloop()

Scrollbar horizontale

Pour un défilement horizontal, on change orient et on utilise xscrollcommand / xview à la place :

📋 Copier le code

import tkinter as tk

fenetre = tk.Tk()
fenetre.title("Scrollbar horizontale")
fenetre.geometry("300x180")

frame = tk.Frame(fenetre)
frame.pack(padx=10, pady=10, fill="both", expand=True)

# Zone Text sans retour à la ligne automatique
zone = tk.Text(frame, wrap="none", height=6)
zone.pack(fill="both", expand=True)

scrollbar_h = tk.Scrollbar(frame, orient="horizontal", command=zone.xview)
scrollbar_h.pack(fill="x")

zone.config(xscrollcommand=scrollbar_h.set)

# Insérer des lignes très longues pour tester
for i in range(1, 8):
    zone.insert(tk.END, f"Ligne {i} — " + "contenu très long qui dépasse la largeur visible " * 3 + "\n")

fenetre.mainloop()

Le paramètre wrap="none" est indispensable ici : sans lui, le widget Text revient automatiquement à la ligne et la scrollbar horizontale n'a rien à montrer. Pour les Canvas et le widget Treeview, le raccordement fonctionne de la même façon.

Par carabde | Mis à jour le 30 avril 2025