Praktisches CRUD-Tutorial: Task-Manager mit Python und Tkinter bauen
CRUD (Create, Read, Update, Delete) ist ein grundlegendes Muster für Datenoperationen. In diesem Tutorial setzen wir es praktisch um, indem wir einen Desktop-Task-Manager mit Python, Tkinter und JSON als Datenspeicher bauen. Ideal für Entwickler, die OOP-Grundlagen, Dateihandling und GUI-Entwicklung festigen möchten.
App-Architektur und Einrichtung
Unsere App läuft in einer einzigen app.py-Datei. Wir nutzen JSON für den Datenspeicher – einfach und unkompliziert für solche Projekte. Jede Aufgabe ist ein Dictionary mit id (eindeutige Kennung), text (Beschreibung) und completed (Status). Alle Aufgaben werden in einer Liste gespeichert und in tasks.json serialisiert.
Stellen Sie sicher, dass Python 3.6 oder neuer installiert ist. Tkinter ist integriert, keine zusätzlichen Pakete nötig. Erstellen Sie einen neuen Projektordner und öffnen Sie ihn in Ihrer IDE.
Datenmodell und JSON-Handling
Zuerst implementieren wir Funktionen zum Laden und Speichern von Daten – die Basis für Read- und Update-CRUD-Operationen.
import json
import os
TASKS_FILE = "tasks.json"
def load_tasks():
"""Lädt Aufgaben aus JSON-Datei."""
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):
"""Speichert Aufgabenliste in JSON-Datei."""
with open(TASKS_FILE, "w", encoding="utf-8") as f:
json.dump(tasks, f, ensure_ascii=False, indent=2)
def get_next_id(tasks):
"""Erzeugt nächste eindeutige ID für neue Aufgabe."""
if not tasks:
return 1
return max(task["id"] for task in tasks) + 1
Wichtige Features:
load_tasksbehandelt fehlende oder beschädigte Dateien elegant.ensure_ascii=Falseinjson.dumpsorgt für korrekte Unicode-Unterstützung.indent=2hält JSON lesbar.
GUI mit Tkinter aufbauen
Wir erstellen eine TodoApp-Klasse, die das Hauptfenster und Widgets verwaltet. Die Oberfläche umfasst:
- Eingabefeld für neue Aufgaben.
- Listbox zur Anzeige aller Aufgaben.
- Steuerungsbuttons: Hinzufügen, Als erledigt markieren, Löschen.
import tkinter as tk
from tkinter import messagebox
class TodoApp:
def __init__(self, root):
self.root = root
self.root.title("Task-Manager")
self.root.geometry("500x400")
self.root.resizable(False, False)
self.tasks = load_tasks()
self.create_widgets()
self.refresh_task_list()
def create_widgets(self):
"""Richtet alle UI-Elemente ein."""
# Oberer Bereich: Eingabe und Hinzufügen-Button
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="➕ Hinzufügen", command=self.add_task)
self.add_button.pack(side=tk.RIGHT)
# Aufgabenliste mit Scrollbar
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)
# Unterer Bereich: Aktionsbuttons
bottom_frame = tk.Frame(self.root)
bottom_frame.pack(pady=10, padx=10, fill=tk.X)
self.done_button = tk.Button(bottom_frame, text="✅ Erledigt", command=self.mark_done)
self.done_button.pack(side=tk.LEFT, padx=5)
self.delete_button = tk.Button(bottom_frame, text="🗑 Löschen", command=self.delete_task)
self.delete_button.pack(side=tk.LEFT, padx=5)
self.exit_button = tk.Button(bottom_frame, text="Beenden", command=self.root.quit)
self.exit_button.pack(side=tk.RIGHT, padx=5)
def refresh_task_list(self):
"""Aktualisiert die Anzeige der Aufgabenliste."""
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 übernimmt die Read-Operation und zeigt den aktuellen Datenstand. Häkchen (✓/○) visualisieren den Erledigungsstatus.
CRUD-Operationen implementieren
Als Nächstes fügen wir Methoden zur Klasse für Benutzeraktionen hinzu, jeweils einer CRUD-Operation zugeordnet.
Create: Neue Aufgabe hinzufügen
def add_task(self):
"""Fügt neue Aufgabe hinzu (Create)."""
text = self.entry.get().strip()
if not text:
messagebox.showwarning("Warnung", "Aufgabentext eingeben")
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("Erfolg", f"Aufgabe hinzugefügt (ID: {next_id})")
Update: Aufgabe als erledigt markieren
def mark_done(self):
"""Markiert ausgewählte Aufgabe als erledigt (Update)."""
selection = self.task_listbox.curselection()
if not selection:
messagebox.showwarning("Warnung", "Aufgabe auswählen")
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", "Aufgabe bereits erledigt")
else:
task["completed"] = True
save_tasks(self.tasks)
self.refresh_task_list()
messagebox.showinfo("Erfolg", f"Aufgabe #{task_id} als erledigt markiert")
return
Delete: Aufgabe löschen
def delete_task(self):
"""Löscht ausgewählte Aufgabe (Delete)."""
selection = self.task_listbox.curselection()
if not selection:
messagebox.showwarning("Warnung", "Aufgabe auswählen")
return
index = selection[0]
task_id = self.tasks[index]["id"]
task_text = self.tasks[index]["text"]
if messagebox.askyesno("Bestätigen", f"Aufgabe #{task_id} \"{task_text}\" löschen?"):
del self.tasks[index]
save_tasks(self.tasks)
self.refresh_task_list()
messagebox.showinfo("Erfolg", f"Aufgabe #{task_id} gelöscht")
Jede Methode validiert Eingaben, aktualisiert Daten im Speicher, speichert in die Datei und erfrischt die UI. Messageboxen geben klare Rückmeldungen.
App zusammenbauen und starten
Alles in einer Datei mit Haupt-Einstiegspunkt verbinden.
if __name__ == "__main__":
root = tk.Tk()
app = TodoApp(root)
root.mainloop()
Mit python app.py starten. Testen Sie alle CRUD-Operationen – die App speichert Daten in tasks.json zwischen Sitzungen.
Wichtige Erkenntnisse
- CRUD-Grundlagen: Create, Read, Update, Delete treibt die meisten datengetriebenen Apps an.
- JSON-Speicher: Perfekt für kleine Projekte – keine Datenbank nötig.
- Tkinter-GUI: Schnelle, plattformübergreifende Desktop-Oberflächen ohne Abhängigkeiten.
- Saubere Code-Struktur: Trennt Datenmodell (JSON), View (Tkinter) und Logik (TodoApp) für einfache Wartung.
- Fehlerbehandlung: Validiert Eingaben und fängt Probleme wie fehlerhaftes JSON ab.
Nächste Schritte
Erweitern Sie Ihren Task-Manager:
- Aufgabenkategorien mit Filterung.
- Fristen mit
datetimeund Farbkodierung. - Export nach CSV oder Excel.
- Datenbank-Integration (SQLite, PostgreSQL).
- Web-Version mit Flask oder Django.
Dieses Projekt zeigt, wie grundlegende Programmierkonzepte in realen Apps angewendet werden und bildet eine starke Basis für fortgeschrittene Themen.
— Editorial Team
Noch keine Kommentare.