# Application ToDo Tkinter : Filtres, Recherche et Export CSV
L'intégration directe de la sélection de priorité dans le panneau de saisie accélère la création des tâches. Nous remplaçons la boîte de dialogue modale par un ttk.Combobox proposant les options haute, moyenne et basse. L'ajout par Entrée fluidifie le flux de travail.
Dans create_widgets, ajoutez un cadre avec Entry, Combobox et bouton :
from tkinter import ttk
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())
tk.Label(top_frame, text="Priorité :").pack(side=tk.LEFT, padx=(5, 2))
self.priority_var = tk.StringVar(value="medium")
priority_combo = ttk.Combobox(
top_frame,
textvariable=self.priority_var,
values=["high", "medium", "low"],
state="readonly",
width=8
)
priority_combo.pack(side=tk.LEFT, padx=(0, 5))
priority_combo.set("medium")
self.add_button = tk.Button(top_frame, text="➕ Ajouter", command=self.add_task, bg="light blue")
self.add_button.pack(side=tk.RIGHT)
La méthode add_task est simplifiée : elle récupère les données de self.entry et self.priority_var.get(), enregistre la tâche, vide le champ et rafraîchit la liste.
Filtrage des Tâches par Statut
Des boutons radio basculent les vues : toutes les tâches, actives uniquement ou terminées. La logique de filtrage s'intègre dans get_sorted_tasks.
Dans __init__, ajoutez self.filter_mode = "all". Dans create_widgets, ajoutez un panneau de filtre avec des Radiobuttons :
filter_frame = tk.Frame(self.root)
filter_frame.pack(pady=5, padx=10, fill=tk.X)
tk.Label(filter_frame, text="Filtre :").pack(side=tk.LEFT, padx=(0, 10))
self.filter_var = tk.StringVar(value="all")
tk.Radiobutton(filter_frame, text="Toutes", variable=self.filter_var,
value="all", command=self.refresh_task_list).pack(side=tk.LEFT, padx=5)
tk.Radiobutton(filter_frame, text="Actives", variable=self.filter_var,
value="active", command=self.refresh_task_list).pack(side=tk.LEFT, padx=5)
tk.Radiobutton(filter_frame, text="Terminées", variable=self.filter_var,
value="completed", command=self.refresh_task_list).pack(side=tk.LEFT, padx=5)
Dans refresh_task_list : self.filter_mode = self.filter_var.get().
get_sorted_tasks filtre d'abord par statut, puis trie les tâches actives par ID en haut, terminées en bas :
def get_sorted_tasks(self):
if self.filter_mode == "active":
filtered_tasks = [task for task in self.tasks if not task["completed"]]
elif self.filter_mode == "completed":
filtered_tasks = [task for task in self.tasks if task["completed"]]
else:
filtered_tasks = self.tasks.copy()
active_tasks = [task for task in filtered_tasks if not task["completed"]]
completed_tasks = [task for task in filtered_tasks if task["completed"]]
active_tasks.sort(key=lambda x: x["id"])
completed_tasks.sort(key=lambda x: x["id"])
return active_tasks + completed_tasks
Recherche en Temps Réel par Texte de Tâche
Un champ de recherche avec liaison <KeyRelease> permet un filtrage instantané en plus du filtre de statut. Un bouton Effacer réinitialise la requête.
Dans create_widgets, ajoutez search_frame :
search_frame = tk.Frame(self.root)
search_frame.pack(pady=(0, 5), padx=10, fill=tk.X)
tk.Label(search_frame, text="Recherche :").pack(side=tk.LEFT, padx=(0, 5))
self.search_entry = tk.Entry(search_frame, font=("Arial", 10))
self.search_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)
self.search_entry.bind("<KeyRelease>", lambda event: self.refresh_task_list())
clear_btn = tk.Button(search_frame, text="✖", command=self.clear_search, width=3)
clear_btn.pack(side=tk.RIGHT, padx=(5, 0))
clear_search vide self.search_entry et appelle refresh_task_list.
get_sorted_tasks s'étend avec un second filtre par search_text = self.search_entry.get().strip().lower() :
search_text = self.search_entry.get().strip().lower()
if search_text:
filtered_tasks = [task for task in filtered_tasks if search_text in task["text"].lower()]
La recherche est insensible à la casse et s'applique après le filtrage par statut.
- Avantages de la recherche en temps réel : Latence minimale grâce aux compréhensions de listes.
- Limites : Recherche linéaire O(n), adaptée à <1000 tâches.
- Optimisation : Pour des listes plus grandes, envisagez bisect ou indexation externe.
Export des Données Filtrées vers CSV
L'export capture la vue actuelle de la liste (après tous les filtres/recherches). Utilise csv.writer avec BOM UTF-8 pour compatibilité Excel. Délimiteur point-virgule, en-têtes : ID, Texte, Statut, Priorité, Date de Création.
Bouton dans bottom_frame :
self.export_button = tk.Button(bottom_frame, text="📎 Exporter en CSV", command=self.export_to_csv, bg="light cyan")
self.export_button.pack(side=tk.LEFT, padx=5)
export_to_csv :
import csv
from tkinter import filedialog
def export_to_csv(self):
tasks_to_export = self.get_sorted_tasks()
if not tasks_to_export:
messagebox.showinfo("Info", "Aucune tâche à exporter")
return
filename = filedialog.asksaveasfilename(
defaultextension=".csv",
filetypes=[("Fichiers CSV", "*.csv"), ("Tous fichiers", "*.*")],
title="Enregistrer en CSV"
)
if not filename:
return
try:
with open(filename, 'w', encoding='utf-8-sig', newline='') as f:
writer = csv.writer(f, delimiter=';')
writer.writerow(['ID', 'Texte', 'Statut', 'Priorité', 'Créée'])
for task in tasks_to_export:
status = "Terminée" if task["completed"] else "Active"
try:
created = datetime.fromisoformat(task["created_at"])
date_str = created.strftime("%d.%m.%Y %H:%M:%S")
except:
date_str = task["created_at"]
priority_map = {"high": "Haute", "medium": "Moyenne", "low": "Basse"}
priority_display = priority_map.get(task["priority"], task["priority"])
writer.writerow([task["id"], task["text"], status, priority_display, date_str])
messagebox.showinfo("Succès", f"Tâches exportées vers :
{filename}")
except Exception as e:
messagebox.showerror("Erreur", f"Échec de l'enregistrement : {e}")
Points Clés
- Intégration Combobox pour les priorités simplifie l'UX sans popups.
- Filtrage combiné (statut + recherche) exploite les compréhensions de listes en chaîne pour la rapidité.
- Export CSV avec UTF-8-sig et ';' fonctionne parfaitement avec Excel sous Windows.
- Mises à jour en temps réel via les liaisons
<KeyRelease>et commandes Radiobutton. - Tri priorise toujours les tâches actives en haut.
— Editorial Team
Aucun commentaire pour le moment.