Affichage et gestion des données hiérarchiques avec Treeview en Python

Dans cet article, nous allons expliquer comment afficher et gérer des données hiérarchiques à l’aide de Treeview en Python, depuis les concepts de base jusqu’aux applications avancées. Treeview est un moyen puissant pour afficher visuellement des données hiérarchiques et rend la structure des données plus intuitive à comprendre. Nous verrons comment implémenter Treeview en Python, comment le personnaliser, des exemples d’applications pratiques, ainsi que des exercices pour renforcer la compréhension.

Sommaire

Concepts de base de Treeview et ses applications

Treeview est un composant d’interface utilisateur utilisé pour afficher visuellement des données hiérarchiques. Il est idéal pour afficher des structures de répertoires, des organigrammes, des données catégorisées, etc. L’utilisation de Treeview permet aux utilisateurs de comprendre facilement les relations parent-enfant et la structure des données, tout en rendant les opérations plus simples.

Structure de Treeview

Un Treeview est composé d’éléments appelés nœuds (node). Chaque nœud peut avoir un nœud parent et un ou plusieurs nœuds enfants, formant ainsi une structure en arbre. Les nœuds peuvent être dépliés (expand) ou repliés (collapse) pour afficher ou masquer des informations détaillées selon les besoins.

Applications de Treeview

Treeview est largement utilisé dans les contextes suivants :

Navigation dans les systèmes de fichiers

Affichage de la structure des répertoires dans les systèmes d’exploitation ou les gestionnaires de fichiers.

Affichage hiérarchique des données

Affichage des relations entre les tables dans les bases de données ou la structure des données XML/JSON.

Navigation dans les applications

Affichage de la structure des projets ou des menus dans les environnements de développement intégré (IDE) ou les systèmes de gestion de contenu (CMS).

Implémentation de Treeview en Python

Pour implémenter Treeview en Python, il est nécessaire d’utiliser une bibliothèque GUI appropriée. Tkinter est une bibliothèque populaire qui fournit un puissant composant Treeview tout en étant simple à utiliser. Cette section présente les étapes de base pour implémenter un Treeview avec Tkinter.

Préparation de l’environnement

Tout d’abord, installez la bibliothèque Tkinter dans votre environnement Python. Tkinter fait partie de la bibliothèque standard de Python, donc normalement aucune installation supplémentaire n’est nécessaire.

Création d’un Treeview de base

Ensuite, nous allons créer un Treeview de base en utilisant Tkinter. L’exemple de code ci-dessous montre comment créer un Treeview simple.

import tkinter as tk
from tkinter import ttk

# Création de la fenêtre principale
root = tk.Tk()
root.title("Exemple de Treeview")

# Création du widget Treeview
tree = ttk.Treeview(root)
tree.pack(expand=True, fill='both')

# Ajout du nœud racine
root_node = tree.insert("", "end", text="Nœud Racine")

# Ajout des nœuds enfants
child_node1 = tree.insert(root_node, "end", text="Nœud Enfant 1")
child_node2 = tree.insert(root_node, "end", text="Nœud Enfant 2")

# Ajout de sous-nœuds
tree.insert(child_node1, "end", text="Sous-Nœud Enfant 1")
tree.insert(child_node2, "end", text="Sous-Nœud Enfant 2")

# Démarrer la boucle principale
root.mainloop()

Explication du code

Le code ci-dessus crée un Treeview avec les étapes suivantes :

  1. Création de la fenêtre principale Tkinter.
  2. Création du widget ttk.Treeview et ajout du Treeview à la fenêtre principale.
  3. Ajout du nœud racine et des nœuds enfants à l’aide de la méthode insert.
  4. Lancement de la boucle principale de l’application avec root.mainloop().

Ce code de base peut être étendu pour ajouter, supprimer, ou personnaliser les nœuds, comme nous allons le voir dans les sections suivantes.

Création d’un Treeview avec Tkinter

Tkinter est une bibliothèque standard de Python qui permet de créer facilement des applications GUI simples. Dans cette section, nous allons utiliser Tkinter pour créer un Treeview et effectuer des opérations de base.

Structure de base d’un Treeview

En utilisant le widget ttk.Treeview de Tkinter, nous allons créer un Treeview avec une structure de base. Le code ci-dessous montre comment faire cela.

import tkinter as tk
from tkinter import ttk

# Création de la fenêtre principale
root = tk.Tk()
root.title("Exemple de Treeview avec Tkinter")

# Création du widget Treeview
tree = ttk.Treeview(root, columns=("size", "modified"), show="headings")
tree.pack(expand=True, fill='both')

# Définition des en-têtes des colonnes
tree.heading("size", text="Taille")
tree.heading("modified", text="Modifié")

# Ajout des données exemple
tree.insert("", "end", text="Dossier 1", values=("2 Ko", "01/01/2024"))
tree.insert("", "end", text="Dossier 2", values=("4 Ko", "01/02/2024"))

# Ajout de sous-nœuds
folder1 = tree.insert("", "end", text="Dossier 1")
tree.insert(folder1, "end", text="Fichier 1", values=("1 Ko", "01/01/2024"))
tree.insert(folder1, "end", text="Fichier 2", values=("1 Ko", "01/01/2024"))

# Démarrer la boucle principale
root.mainloop()

Explication du code

Le code ci-dessus crée un Treeview avec les étapes suivantes :

  1. Création de la fenêtre principale : création de la fenêtre principale Tkinter et définition de son titre.
  2. Création du widget Treeview : création du widget ttk.Treeview et définition des colonnes pour afficher les en-têtes et les valeurs.
  3. Définition des en-têtes : définition des en-têtes des colonnes à l’aide de la méthode heading.
  4. Ajout des données exemple : utilisation de la méthode insert pour ajouter des dossiers et des fichiers, ainsi que leurs informations (taille et date de modification).
  5. Ajout de sous-nœuds : ajout de fichiers sous les dossiers en utilisant la méthode insert.
  6. Début de la boucle principale : démarrage de la boucle principale avec root.mainloop() pour afficher la fenêtre et interagir avec l’utilisateur.

Ce Treeview de base peut être étendu pour inclure des fonctionnalités de gestion des données comme l’ajout et la suppression dynamique, comme nous le verrons plus loin.

Ajout et suppression de données dans Treeview

Ajouter et supprimer des données dans Treeview est essentiel pour la gestion et la mise à jour des données. Dans cette section, nous expliquerons comment ajouter et supprimer des nœuds dans Treeview à l’aide de Tkinter.

Ajout de données

Pour ajouter des données à Treeview, on utilise la méthode insert. L’exemple suivant montre comment ajouter un nouveau nœud.

import tkinter as tk
from tkinter import ttk

# Création de la fenêtre principale
root = tk.Tk()
root.title("Opérations de données sur Treeview")

# Création du widget Treeview
tree = ttk.Treeview(root)
tree.pack(expand=True, fill='both')

# Ajout du nœud racine
root_node = tree.insert("", "end", text="Nœud Racine")

# Fonction pour ajouter des données
def add_data():
    tree.insert(root_node, "end", text="Nouveau Nœud Enfant")

# Création du bouton
add_button = tk.Button(root, text="Ajouter des données", command=add_data)
add_button.pack()

# Démarrer la boucle principale
root.mainloop()

Explication du code

  1. Création du widget Treeview : création du widget Treeview et ajout à la fenêtre principale.
  2. Ajout du nœud racine : ajout du nœud racine en utilisant insert.
  3. Définition de la fonction pour ajouter des données : création de la fonction add_data qui ajoute un nouveau nœud enfant au nœud racine.
  4. Création du bouton : création d’un bouton pour ajouter un nœud à chaque clic.

Suppression de données

Pour supprimer des données de Treeview, on utilise la méthode delete. L’exemple ci-dessous montre comment supprimer un nœud sélectionné.

import tkinter as tk
from tkinter import ttk

# Création de la fenêtre principale
root = tk.Tk()
root.title("Suppression de données dans Treeview")

# Création du widget Treeview
tree = ttk.Treeview(root)
tree.pack(expand=True, fill='both')

# Ajout du nœud racine et du nœud enfant
root_node = tree.insert("", "end", text="Nœud Racine")
child_node = tree.insert(root_node, "end", text="Nœud Enfant")

# Fonction pour supprimer des données
def delete_data():
    selected_item = tree.selection()[0]
    tree.delete(selected_item)

# Création du bouton
delete_button = tk.Button(root, text="Supprimer des données", command=delete_data)
delete_button.pack()

# Démarrer la boucle principale
root.mainloop()

Explication du code

  1. Création du widget Treeview : création du widget Treeview et ajout à la fenêtre principale.
  2. Ajout du nœud racine et du nœud enfant : ajout des nœuds à l’aide de insert.
  3. Définition de la fonction pour supprimer des données : création de la fonction delete_data qui supprime un nœud sélectionné à l’aide de selection et delete.
  4. Création du bouton : création d’un bouton pour supprimer un nœud sélectionné.

Ces opérations vous permettent d’ajouter et de supprimer dynamiquement des nœuds dans Treeview. Passons maintenant à la personnalisation de l’apparence de Treeview.

Personnalisation de Treeview

La personnalisation de Treeview permet d’adapter son apparence et son comportement aux besoins de l’utilisateur. Dans cette section, nous allons explorer comment personnaliser l’apparence et le fonctionnement de Treeview.

Ajout et personnalisation des colonnes

Voyons comment ajouter et personnaliser les colonnes dans Treeview. L’exemple suivant montre comment ajouter des colonnes et définir les en-têtes de celles-ci.

import tkinter as tk
from tkinter import ttk

# Création de la fenêtre principale
root = tk.Tk()
root.title("Personnalisation de Treeview")

# Création du widget Treeview
tree = ttk.Treeview(root, columns=("size", "modified"), show="headings")
tree.pack(expand=True, fill='both')

# Définition des colonnes
tree.heading("size", text="Taille")
tree.heading("modified", text="Modifié")

# Définition de la largeur des colonnes
tree.column("size", width=100)
tree.column("modified", width=150)

# Ajout des données exemple
tree.insert("", "end", values=("2 Ko", "01/01/2024"))
tree.insert("", "end", values=("4 Ko", "01/02/2024"))

# Démarrer la boucle principale
root.mainloop()

Explication du code

  1. Ajout de colonnes : définition des colonnes avec l’argument columns et affichage des en-têtes avec show="headings".
  2. Définition des en-têtes : utilisation de heading pour définir les en-têtes de chaque colonne.
  3. Définition de la largeur des colonnes : utilisation de column pour définir la largeur des colonnes.

Personnalisation des nœuds

Il est également possible de personnaliser l’apparence des nœuds. L’exemple suivant montre comment ajouter des icônes aux nœuds.

import tkinter as tk
from tkinter import ttk

# Création de la fenêtre principale
root = tk.Tk()
root.title("Personnalisation des nœuds de Treeview")

# Création du widget Treeview
tree = ttk.Treeview(root)
tree.pack(expand=True, fill='both')

# Chargement des icônes
folder_icon = tk.PhotoImage(file="folder.png")
file_icon = tk.PhotoImage(file="file.png")

# Ajout du nœud racine
root_node = tree.insert("", "end", text="Nœud Racine", image=folder_icon)

# Ajout des sous-nœuds
tree.insert(root_node, "end", text="Nœud Enfant 1", image=file_icon)
tree.insert(root_node, "end", text="Nœud Enfant 2", image=file_icon)

# Démarrer la boucle principale
root.mainloop()

Explication du code

  1. Chargement des icônes : utilisation de PhotoImage pour charger des images d’icônes.
  2. Ajout d’icônes aux nœuds : spécification des icônes pour les nœuds à l’aide de l’argument image lors de l’ajout des nœuds.

Ajout de gestion d’événements

En ajoutant une gestion d’événements à Treeview, vous pouvez personnaliser le comportement lorsque l’utilisateur clique sur un nœud. L’exemple suivant montre comment afficher un message lorsque l’utilisateur sélectionne un nœud.

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox

# Création de la fenêtre principale
root = tk.Tk()
root.title("Gestion des événements dans Treeview")

# Création du widget Treeview
tree = ttk.Treeview(root)
tree.pack(expand=True, fill='both')

# Ajout des nœuds
root_node = tree.insert("", "end", text="Nœud Racine")
tree.insert(root_node, "end", text="Nœud Enfant 1")
tree.insert(root_node, "end", text="Nœud Enfant 2")

# Définition de l'événement
def on_node_select(event):
    selected_item = tree.selection()[0]
    node_text = tree.item(selected_item, "text")
    messagebox.showinfo("Sélection du nœud", f"Nœud sélectionné : {node_text}")

# Lier l'événement de sélection
tree.bind("<>", on_node_select)

# Démarrer la boucle principale
root.mainloop()

Explication du code

  1. Définition de l’événement : création de la fonction on_node_select qui affiche un message avec le texte du nœud sélectionné.
  2. Liaison de l’événement : utilisation de bind pour lier l’événement de sélection à la fonction on_node_select.

Grâce à ces techniques, vous pouvez personnaliser l’apparence et le comportement de Treeview pour créer des interfaces plus conviviales. Passons maintenant à quelques exemples d’applications concrètes de Treeview.

Exemples d’application de Treeview

Treeview est utilisé dans de nombreuses applications réelles. Cette section présente des exemples concrets de son utilisation en Python et montre comment tirer parti de Treeview dans des applications pratiques.

Création d’un explorateur de fichiers

Treeview est idéal pour la navigation dans les systèmes de fichiers. L’exemple suivant montre comment créer un explorateur de fichiers simple qui affiche la structure des répertoires.

import tkinter as tk
from tkinter import ttk
import os

# Création de la fenêtre principale
root = tk.Tk()
root.title("Explorateur de fichiers")

# Création du widget Treeview
tree = ttk.Treeview(root)
tree.pack(expand=True, fill='both')

# Définition du répertoire racine
root_dir = os.path.expanduser("~")

# Fonction de chargement des répertoires
def load_directory(parent, path):
    for entry in os.listdir(path):
        abs_path = os.path.join(path, entry)
        node = tree.insert(parent, "end", text=entry, open=False)
        if os.path.isdir(abs_path):
            load_directory(node, abs_path)

# Création du nœud racine
root_node = tree.insert("", "end", text=root_dir, open=True)
load_directory(root_node, root_dir)

# Démarrer la boucle principale
root.mainloop()

Explication du code

  1. Définition du répertoire racine : utilisation de os.path.expanduser("~") pour obtenir le répertoire de l’utilisateur.
  2. Fonction de chargement des répertoires : définition de la fonction load_directory qui parcourt le répertoire et ajoute les fichiers et sous-répertoires au Treeview.
  3. Création du nœud racine : création du nœud racine pour le répertoire principal et chargement de la structure des répertoires.
  4. Chargement des sous-répertoires : utilisation de la récursivité pour afficher la structure en arbre des sous-répertoires.

Affichage d’un organigramme

Treeview est également adapté à l’affichage d’organigrammes d’entreprises ou d’organisations. L’exemple suivant montre comment afficher un organigramme simple.

import tkinter as tk
from tkinter import ttk

# Création de la fenêtre principale
root = tk.Tk()
root.title("Organigramme")

# Création du widget Treeview
tree = ttk.Treeview(root)
tree.pack(expand=True, fill='both')

# Données de l'organigramme
organization = {
    "CEO": ["CTO", "CFO", "COO"],
    "CTO": ["Dev Manager", "QA Manager"],
    "CFO": ["Accountant"],
    "COO": ["Operations Manager"],
    "Dev Manager": ["Developer 1", "Developer 2"],
    "QA Manager": ["QA Tester"],
    "Operations Manager": ["Logistics"],
}

# Fonction de chargement de l'organigramme
def load_organization(parent, position):
    node = tree.insert(parent, "end", text=position)
    if position in organization:
        for sub_position in organization[position]:
            load_organization(node, sub_position)

# Ajout de la position racine
root_position = "CEO"
load_organization("", root_position)

# Démarrer la boucle principale
root.mainloop()

Explication du code

  1. Données de l’organigramme : définition de l’organigramme sous forme de dictionnaire, où les clés sont les titres et les valeurs sont les subordonnés de ces titres.
  2. Fonction de chargement de l’organigramme : définition de la fonction load_organization qui ajoute les titres et leurs subordonnés dans Treeview.
  3. Ajout de la position racine : création du nœud racine pour le CEO et chargement de l’organigramme.

Gestion de projet avec Treeview

Treeview peut également être utilisé pour afficher les tâches et sous-tâches d’un projet de manière hiérarchique. L’exemple suivant montre comment gérer les tâches d’un projet avec Treeview.

import tkinter as tk
from tkinter import ttk

# Création de la fenêtre principale
root = tk.Tk()
root.title("Gestion de projet")

# Création du widget Treeview
tree = ttk.Treeview(root)
tree.pack(expand=True, fill='both')

# Données du projet
project = {
    "Project A": ["Task 1", "Task 2"],
    "Task 1": ["Subtask 1.1", "Subtask 1.2"],
    "Task 2": ["Subtask 2.1"],
}

# Fonction de chargement des tâches du projet
def load_project(parent, task):
    node = tree.insert(parent, "end", text=task)
    if task in project:
        for sub_task in project[task]:
            load_project(node, sub_task)

# Ajout de la tâche racine
root_task = "Project A"
load_project("", root_task)

# Démarrer la boucle principale
root.mainloop()

Explication du code

  1. Données du projet : définition des tâches du projet sous forme de dictionnaire.
  2. Fonction de chargement des tâches : définition de la fonction load_project qui ajoute les tâches et sous-tâches au Treeview.
  3. Ajout de la tâche racine : ajout de la tâche principale au Treeview et chargement des sous-tâches.

Grâce à ces exemples, vous comprendrez mieux comment utiliser Treeview pour des projets réels, et comment l’appliquer dans vos propres applications. Nous allons maintenant conclure cet article.

Conclusion

Dans cet article, nous avons expliqué comment afficher et gérer des données hiérarchiques avec Treeview en Python. Nous avons abordé les concepts de base de Treeview, son utilisation dans différents contextes, ainsi que son implémentation avec Tkinter. Nous avons également exploré la personnalisation de Treeview, l’ajout et la suppression de données, et des exemples d’applications réelles telles que l’explorateur de fichiers et la gestion de projet. En appliquant ces connaissances, vous pourrez gérer et afficher efficacement des données hiérarchiques dans vos projets.

Exercices et solutions

Voici quelques exercices pour renforcer votre compréhension de Treeview. En les réalisant, vous apprendrez à manipuler les fonctionnalités de base et avancées de Treeview, telles que l’ajout et la suppression de nœuds, la personnalisation de l’apparence et l’intégration d’événements.

Exercice 1 : Création d’un Treeview de base

Utilisez Tkinter pour créer un Treeview qui affiche une structure hiérarchique comme suit :

  • Racine
  • Branche 1
    • Feuille 1.1
    • Feuille 1.2
  • Branche 2
    • Feuille 2.1
    • Feuille 2.2

Solution

import tkinter as tk
from tkinter import ttk

# Création de la fenêtre principale
root = tk.Tk()
root.title("Treeview de base")

# Création du widget Treeview
tree = ttk.Treeview(root)
tree.pack(expand=True, fill='both')

# Ajout des nœuds
root_node = tree.insert("", "end", text="Racine")
branch1 = tree.insert(root_node, "end", text="Branche 1")
tree.insert(branch1, "end", text="Feuille 1.1")
tree.insert(branch1, "end", text="Feuille 1.2")
branch2 = tree.insert(root_node, "end", text="Branche 2")
tree.insert(branch2, "end", text="Feuille 2.1")
tree.insert(branch2, "end", text="Feuille 2.2")

# Démarrer la boucle principale
root.mainloop()

Exercice 2 : Ajout et suppression de données

Ajoutez des boutons qui permettent d’ajouter dynamiquement de nouveaux nœuds à un Treeview existant et de supprimer un nœud sélectionné. Lorsqu’un bouton « Ajouter » est cliqué, un nouveau nœud doit être ajouté sous la racine, et lorsqu’un bouton « Supprimer » est cliqué, le nœud sélectionné doit être supprimé.

Solution

import tkinter as tk
from tkinter import ttk

# Création de la fenêtre principale
root = tk.Tk()
root.title("Ajout et suppression de données")

# Création du widget Treeview
tree = ttk.Treeview(root)
tree.pack(expand=True, fill='both')

# Ajout des nœuds
root_node = tree.insert("", "end", text="Racine")
branch1 = tree.insert(root_node, "end", text="Branche 1")
tree.insert(branch1, "end", text="Feuille 1.1")
tree.insert(branch1, "end", text="Feuille 1.2")
branch2 = tree.insert(root_node, "end", text="Branche 2")
tree.insert(branch2, "end", text="Feuille 2.1")
tree.insert(branch2, "end", text="Feuille 2.2")

# Fonction pour ajouter un nœud
def add_data():
    tree.insert(root_node, "end", text="Nouvelle Branche")

# Fonction pour supprimer un nœud
def delete_data():
    selected_item = tree.selection()[0]
    tree.delete(selected_item)

# Création des boutons
add_button = tk.Button(root, text="Ajouter des données", command=add_data)
add_button.pack()
delete_button = tk.Button(root, text="Supprimer des données", command=delete_data)
delete_button.pack()

# Démarrer la boucle principale
root.mainloop()

Exercice 3 : Treeview personnalisé

Créez un Treeview qui contient trois colonnes : Nom du Nœud, Taille, et Date de Dernière Modification. Utilisez les colonnes pour afficher les informations associées à chaque nœud et personnalisez la largeur des colonnes.

Solution

import tkinter as tk
from tkinter import ttk

# Création de la fenêtre principale
root = tk.Tk()
root.title("Treeview personnalisé")

# Création du widget Treeview
tree = ttk.Treeview(root, columns=("size", "modified"), show="headings")
tree.pack(expand=True, fill='both')

# Définition des colonnes
tree.heading("size", text="Taille")
tree.heading("modified", text="Dernière Modification")
tree.column("size", width=100)
tree.column("modified", width=150)

# Ajout des nœuds
tree.insert("", "end", text="Racine", values=("2 Ko", "01/01/2024"))
tree.insert("", "end", text="Branche 1", values=("4 Ko", "01/02/2024"))
tree.insert("", "end", text="Branche 2", values=("3 Ko", "01/03/2024"))

# Démarrer la boucle principale
root.mainloop()

Exercice 4 : Gestion d’événements

Ajoutez un gestionnaire d’événements qui affiche le nom du nœud sélectionné lorsque l’utilisateur clique dessus.

Solution

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox

# Création de la fenêtre principale
root = tk.Tk()
root.title("Gestion des événements")

# Création du widget Treeview
tree = ttk.Treeview(root)
tree.pack(expand=True, fill='both')

# Ajout des nœuds
root_node = tree.insert("", "end", text="Racine")
tree.insert(root_node, "end", text="Branche 1")
tree.insert(root_node, "end", text="Branche 2")

# Définition de l'événement
def on_node_select(event):
    selected_item = tree.selection()[0]
    node_text = tree.item(selected_item, "text")
    messagebox.showinfo("Sélection du nœud", f"Nœud sélectionné : {node_text}")

# Lier l'événement
tree.bind("<>", on_node_select)

# Démarrer la boucle principale
root.mainloop()

Ces exercices vous permettent de mieux comprendre comment implémenter et personnaliser Treeview dans Python. En les réalisant, vous serez capable de maîtriser les fonctionnalités de Treeview et d’adapter cet outil puissant à vos besoins spécifiques.

Conclusion

Dans cet article, nous avons exploré la manière d’afficher et de gérer des données hiérarchiques à l’aide de Treeview en Python. Nous avons abordé les concepts de base, la personnalisation de l’affichage, ainsi que des exemples pratiques d’applications. Grâce à ces connaissances, vous pouvez facilement gérer des données hiérarchiques dans vos projets et créer des interfaces utilisateur efficaces. Nous espérons que cet article vous a fourni des outils précieux pour développer vos compétences en programmation avec Python et Tkinter.

Sommaire