Retour à l'accueil

CRUD en Python : création d'un gestionnaire de tâches avec Tkinter et JSON

Guide pratique pour implémenter les opérations CRUD en Python en créant un gestionnaire de tâches de bureau. L'article couvre le travail avec Tkinter pour créer une interface graphique, l'utilisation de JSON pour le stockage des données et les bases de la programmation orientée objet.

Création d'une application CRUD en Python : gestionnaire de tâches de zéro
Advertisement 728x90

# Guide pratique CRUD : Créez un gestionnaire de tâches avec Python et Tkinter

CRUD (Create, Read, Update, Delete) est un modèle fondamental pour les opérations sur les données. Dans ce guide, nous le mettons en pratique en construisant un gestionnaire de tâches de bureau avec Python, Tkinter et JSON pour le stockage des données. Idéal pour les développeurs souhaitant consolider les bases de la POO, la gestion de fichiers et le développement d'interfaces graphiques.

Architecture de l'application et configuration

Notre application tiendra dans un seul fichier app.py. Nous utiliserons JSON pour le stockage des données — simple et efficace pour ce type de projet. Chaque tâche est un dictionnaire avec id (identifiant unique), text (description) et completed (état). Toutes les tâches sont stockées dans une liste, sérialisée dans tasks.json.

Assurez-vous d'avoir Python 3.6 ou supérieur installé. Tkinter est intégré, aucune installation supplémentaire n'est nécessaire. Créez un nouveau dossier de projet et ouvrez-le dans votre IDE.

Google AdInline article slot

Modèle de données et gestion JSON

D'abord, implémentons les fonctions de chargement et sauvegarde des données — la base des opérations Read et Update CRUD.

import json
import os

TASKS_FILE = "tasks.json"

def load_tasks():
    """Charge les tâches depuis le fichier JSON."""
    if not os.path.exists(TASKS_FILE):
        return []
    with open(TASKS_FILE, "r", encoding="utf-8") as f:
        try:
            return json.load(f)
        except json.JSONDecodeError:
            return []

def save_tasks(tasks):
    """Sauvegarde la liste des tâches dans le fichier JSON."""
    with open(TASKS_FILE, "w", encoding="utf-8") as f:
        json.dump(tasks, f, ensure_ascii=False, indent=2)

def get_next_id(tasks):
    """Génère l'ID unique suivant pour une nouvelle tâche."""
    if not tasks:
        return 1
    return max(task["id"] for task in tasks) + 1

Points clés :

  • load_tasks gère gracieusement les fichiers manquants ou corrompus.
  • ensure_ascii=False dans json.dump assure un support Unicode correct.
  • indent=2 rend le JSON lisible.

Construction de l'interface avec Tkinter

Nous créerons une classe TodoApp pour gérer la fenêtre principale et les widgets. L'interface comprend :

Google AdInline article slot
  • Champ de saisie pour les nouvelles tâches.
  • Liste pour afficher toutes les tâches.
  • Boutons de contrôle : ajouter, marquer comme fait, supprimer.
import tkinter as tk
from tkinter import messagebox

class TodoApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Gestionnaire de tâches")
        self.root.geometry("500x400")
        self.root.resizable(False, False)
        self.tasks = load_tasks()
        self.create_widgets()
        self.refresh_task_list()

    def create_widgets(self):
        """Configure tous les éléments d'interface."""
        # Panneau supérieur : saisie et bouton ajouter
        top_frame = tk.Frame(self.root)
        top_frame.pack(pady=10, padx=10, fill=tk.X)
        self.entry = tk.Entry(top_frame, font=("Arial", 12))
        self.entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))
        self.entry.bind("<Return>", lambda event: self.add_task())
        self.add_button = tk.Button(top_frame, text="➕ Ajouter", command=self.add_task)
        self.add_button.pack(side=tk.RIGHT)
        # Liste des tâches avec barre de défilement
        list_frame = tk.Frame(self.root)
        list_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
        scrollbar = tk.Scrollbar(list_frame)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.task_listbox = tk.Listbox(
            list_frame,
            font=("Arial", 11),
            yscrollcommand=scrollbar.set,
            selectmode=tk.SINGLE,
            height=15
        )
        self.task_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=self.task_listbox.yview)
        # Panneau inférieur : boutons d'action
        bottom_frame = tk.Frame(self.root)
        bottom_frame.pack(pady=10, padx=10, fill=tk.X)
        self.done_button = tk.Button(bottom_frame, text="✅ Terminé", command=self.mark_done)
        self.done_button.pack(side=tk.LEFT, padx=5)
        self.delete_button = tk.Button(bottom_frame, text="🗑 Supprimer", command=self.delete_task)
        self.delete_button.pack(side=tk.LEFT, padx=5)
        self.exit_button = tk.Button(bottom_frame, text="Quitter", command=self.root.quit)
        self.exit_button.pack(side=tk.RIGHT, padx=5)

    def refresh_task_list(self):
        """Actualise l'affichage de la liste des tâches."""
        self.task_listbox.delete(0, tk.END)
        for task in self.tasks:
            status = "✓" if task["completed"] else "○"
            display_text = f"{status} {task['id']}. {task['text']}"
            self.task_listbox.insert(tk.END, display_text)

refresh_task_list gère l'opération Read, affichant l'état actuel des données. Les coches (✓/○) visualisent l'état de complétion.

Mise en œuvre des opérations CRUD

Ajoutons ensuite les méthodes à la classe pour les actions utilisateur, chacune liée à une opération CRUD.

Create : Ajouter une nouvelle tâche

    def add_task(self):
        """Ajoute une nouvelle tâche (Create)."""
        text = self.entry.get().strip()
        if not text:
            messagebox.showwarning("Attention", "Saisissez le texte de la tâche")
            return
        next_id = get_next_id(self.tasks)
        new_task = {
            "id": next_id,
            "text": text,
            "completed": False
        }
        self.tasks.append(new_task)
        save_tasks(self.tasks)
        self.entry.delete(0, tk.END)
        self.refresh_task_list()
        messagebox.showinfo("Succès", f"Tâche ajoutée (ID : {next_id})")

Update : Marquer une tâche comme terminée

    def mark_done(self):
        """Marque la tâche sélectionnée comme terminée (Update)."""
        selection = self.task_listbox.curselection()
        if not selection:
            messagebox.showwarning("Attention", "Sélectionnez une tâche")
            return
        index = selection[0]
        task_id = self.tasks[index]["id"]
        for task in self.tasks:
            if task["id"] == task_id:
                if task["completed"]:
                    messagebox.showinfo("Info", "Tâche déjà terminée")
                else:
                    task["completed"] = True
                    save_tasks(self.tasks)
                    self.refresh_task_list()
                    messagebox.showinfo("Succès", f"Tâche #{task_id} marquée terminée")
                return

Delete : Supprimer une tâche

    def delete_task(self):
        """Supprime la tâche sélectionnée (Delete)."""
        selection = self.task_listbox.curselection()
        if not selection:
            messagebox.showwarning("Attention", "Sélectionnez une tâche")
            return
        index = selection[0]
        task_id = self.tasks[index]["id"]
        task_text = self.tasks[index]["text"]
        if messagebox.askyesno("Confirmer", f"Supprimer la tâche #{task_id} \"{task_text}\" ?"):
            del self.tasks[index]
            save_tasks(self.tasks)
            self.refresh_task_list()
            messagebox.showinfo("Succès", f"Tâche #{task_id} supprimée")

Chaque méthode valide les entrées, met à jour les données en mémoire, sauvegarde dans le fichier et actualise l'interface. Les boîtes de dialogue fournissent un retour clair à l'utilisateur.

Google AdInline article slot

Assemblage et exécution de l'application

Rassemblez tout dans un seul fichier avec un point d'entrée principal.

if __name__ == "__main__":
    root = tk.Tk()
    app = TodoApp(root)
    root.mainloop()

Lancez avec python app.py. Testez toutes les opérations CRUD — l'application sauvegarde les données dans tasks.json entre les sessions.

Points clés à retenir

  • Fondamentaux CRUD : Create, Read, Update, Delete alimente la plupart des applications basées sur des données.
  • Stockage JSON : Idéal pour les petits projets — pas besoin de base de données.
  • Interface Tkinter : Interfaces de bureau rapides, multiplateformes sans dépendances.
  • Structure de code propre : Sépare le modèle de données (JSON), la vue (Tkinter) et la logique (TodoApp) pour une maintenance facile.
  • Gestion d'erreurs : Valide les entrées et gère les problèmes comme un JSON défectueux.

Prochaines étapes

Améliorez votre gestionnaire de tâches :

  • Catégories de tâches avec filtrage.
  • Échéances avec datetime et codage par couleurs.
  • Export vers CSV ou Excel.
  • Intégration base de données (SQLite, PostgreSQL).
  • Version web avec Flask ou Django.

Ce projet montre comment les concepts fondamentaux de programmation s'appliquent aux applications réelles, posant une base solide pour des sujets avancés.

— Editorial Team

Advertisement 728x90

Lire ensuite