logo oujood
🔍

Le widget Treeview Tkinter (ttk)

Treeview sert à la fois de tableau de données et d'arborescence hiérarchique. C'est le widget ttk le plus polyvalent pour afficher des informations structurées.

OUJOOD.COM

Le widget Treeview du module ttk remplit deux rôles selon la façon dont on le configure : tableau de données avec colonnes (comme une mini feuille de calcul) ou arborescence hiérarchique (comme un explorateur de fichiers). Dans la pratique, c'est surtout son usage en tableau qui revient le plus souvent.

Treeview en mode tableau

On définit les colonnes, on masque la colonne d'arborescence par défaut, puis on insère des lignes :

📋 Copier le code

import tkinter as tk
from tkinter import ttk

fenetre = tk.Tk()
fenetre.title("Treeview — tableau")
fenetre.geometry("480x260")

colonnes = ("nom", "age", "ville")

tableau = ttk.Treeview(fenetre, columns=colonnes, show="headings", height=8)

# Définir les en-têtes et largeurs
tableau.heading("nom",   text="Nom")
tableau.heading("age",   text="Âge")
tableau.heading("ville", text="Ville")

tableau.column("nom",   width=160)
tableau.column("age",   width=60,  anchor="center")
tableau.column("ville", width=160)

tableau.pack(padx=15, pady=15, fill="both", expand=True)

# Insérer des données
donnees = [
    ("Alice Martin",   28, "Paris"),
    ("Bob Durand",     34, "Lyon"),
    ("Claire Petit",   22, "Bordeaux"),
    ("David Moreau",   45, "Marseille"),
    ("Emma Leroy",     31, "Toulouse"),
]

for nom, age, ville in donnees:
    tableau.insert("", tk.END, values=(nom, age, ville))

fenetre.mainloop()

show="headings" masque la colonne d'arborescence vide qui apparaît par défaut à gauche — indispensable pour un tableau simple. anchor="center" dans column() centre le contenu de la colonne. insert("", tk.END, values=...) ajoute une ligne à la racine de l'arborescence.

Lire la sélection et supprimer des lignes

📋 Copier le code

import tkinter as tk
from tkinter import ttk

fenetre = tk.Tk()
fenetre.geometry("480x300")

colonnes = ("produit", "prix", "stock")
tableau = ttk.Treeview(fenetre, columns=colonnes, show="headings", height=7)

for col in colonnes:
    tableau.heading(col, text=col.capitalize())
    tableau.column(col, width=140, anchor="center")

tableau.pack(padx=15, pady=10, fill="both", expand=True)

produits = [("Clavier", "49.90 €", 12), ("Souris", "29.90 €", 8),
            ("Écran",   "299 €",   3),  ("Webcam", "79 €",    6)]

for p in produits:
    tableau.insert("", tk.END, values=p)

def lire_selection():
    selection = tableau.selection()    # tuple d'IDs des lignes sélectionnées
    if selection:
        item = tableau.item(selection[0])  # dict avec 'values', 'text', 'tags'
        label.config(text=f"Sélectionné : {item['values'][0]}")

def supprimer():
    for item_id in tableau.selection():
        tableau.delete(item_id)

frame_btn = tk.Frame(fenetre)
frame_btn.pack()
tk.Button(frame_btn, text="Lire",      command=lire_selection).pack(side="left", padx=5)
tk.Button(frame_btn, text="Supprimer", command=supprimer).pack(side="left", padx=5)
label = tk.Label(fenetre, text="")
label.pack(pady=5)

fenetre.mainloop()

tableau.selection() retourne un tuple d'identifiants internes. tableau.item(id) retourne un dictionnaire avec les données de la ligne — la clé values contient le tuple de valeurs passé à insert(). Pour parcourir toutes les lignes : tableau.get_children() retourne tous les IDs.

Trier les colonnes au clic sur l'en-tête

Le tri sur clic d'en-tête n'est pas natif — il faut le programmer avec bind() :

📋 Copier le code

import tkinter as tk
from tkinter import ttk

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

colonnes = ("pays", "population")
tableau = ttk.Treeview(fenetre, columns=colonnes, show="headings", height=7)
tableau.pack(padx=10, pady=10, fill="both", expand=True)

ordre_tri = {}  # mémorise le sens de tri par colonne

def trier_colonne(col):
    donnees = [(tableau.set(k, col), k) for k in tableau.get_children("")]
    inverse = ordre_tri.get(col, False)
    donnees.sort(reverse=inverse, key=lambda x: x[0].lower() if isinstance(x[0], str) else float(x[0]))
    for index, (_, k) in enumerate(donnees):
        tableau.move(k, "", index)
    ordre_tri[col] = not inverse

for col in colonnes:
    tableau.heading(col, text=col.capitalize(),
                    command=lambda c=col: trier_colonne(c))
    tableau.column(col, width=180, anchor="center")

pays_data = [("France", "68 M"), ("Allemagne", "84 M"), ("Maroc", "37 M"),
             ("Espagne", "47 M"), ("Belgique", "11 M"), ("Canada", "38 M")]

for p in pays_data:
    tableau.insert("", tk.END, values=p)

fenetre.mainloop()

Chaque clic sur un en-tête alterne entre tri croissant et décroissant. tableau.move(k, "", index) déplace la ligne à sa nouvelle position sans recréer les données. Ce widget fonctionne naturellement avec des données chargées depuis un fichier CSV avec Pandasdf.values.tolist() produit directement le format attendu par insert().

Par carabde | Mis à jour le 30 avril 2025