Zpět na domů

CRUD v Pythonu: vytváříme správce úkolů s Tkinter a JSON

Praktické pokyny k implementaci CRUD operací v Pythonu prostřednictvím vytvoření desktopového správce úkolů. Článek pokrývá práci s Tkinter pro vytvoření grafického rozhraní, použití JSON pro ukládání dat a základy objektově orientovaného programování.

Vytváříme CRUD aplikaci v Pythonu: správce úkolů od nuly
Advertisement 728x90

Praktická příručka CRUD: vytvoříme správce úkolů v Pythonu s Tkinterem

CRUD (Create, Read, Update, Delete) je základní vzor pro práci s daty. V této příručce ho uvedeme do praxe vytvořením desktopové aplikace pro správu úkolů s využitím Pythonu, Tkinteru a JSON pro ukládání dat. Projekt je vhodný pro vývojáře, kteří chtějí upevnit základy OOP, práci se soubory a tvorbu grafických rozhraní.

Architektura aplikace a příprava prostředí

Naše aplikace bude sestávat z jednoho souboru app.py. Pro ukládání dat je zvolen JSON formát, jako nejjednodušší a nejnázornější pro podobné úlohy. Každý úkol je reprezentován jako slovník s poli: id (jedinečný identifikátor), text (popis) a completed (stav dokončení). Všechny úkoly jsou uloženy v seznamu, který je serializován do souboru tasks.json.

Před začátkem se ujistěte, že máte nainstalován Python 3.6 nebo vyšší. Tkinter je součástí standardní knihovny, takže není potřeba dodatečná instalace. Vytvořte nový adresář pro projekt a otevřete ho ve své IDE.

Google AdInline article slot

Implementace datového modelu a práce s JSON

Jako první implementujeme funkce pro načítání a ukládání dat. To je základ CRUD operací Read a Update.

import json
import os

TASKS_FILE = "tasks.json"

def load_tasks():
    """Načte seznam úkolů z JSON souboru."""
    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):
    """Uloží seznam úkolů do JSON souboru."""
    with open(TASKS_FILE, "w", encoding="utf-8") as f:
        json.dump(tasks, f, ensure_ascii=False, indent=2)

def get_next_id(tasks):
    """Vygeneruje další jedinečné ID pro nový úkol."""
    if not tasks:
        return 1
    return max(task["id"] for task in tasks) + 1

Klíčové aspekty této implementace:

  • Funkce load_tasks zpracovává případy absence nebo poškození souboru.
  • Parametr ensure_ascii=False v json.dump zajišťuje správné uložení diakritiky.
  • indent=2 formátuje JSON pro čitelnost.

Vytváření grafického rozhraní s Tkinter

Vytvoříme třídu TodoApp, která bude spravovat hlavní okno a widgety. Použijeme Tkinter pro vytvoření rozhraní, které se skládá z:

Google AdInline article slot
  • Vstupního pole pro nový úkol.
  • Seznamu (Listbox) pro zobrazení všech úkolů.
  • Ovládacích tlačítek: přidání, označení jako hotovo, odstranění.
import tkinter as tk
from tkinter import messagebox

class TodoApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Správce úkolů")
        self.root.geometry("500x400")
        self.root.resizable(False, False)
        self.tasks = load_tasks()
        self.create_widgets()
        self.refresh_task_list()

    def create_widgets(self):
        """Inicializuje všechny prvky rozhraní."""
        # Horní panel: vstupní pole a tlačítko pro přidání
        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="➕ Přidat", command=self.add_task)
        self.add_button.pack(side=tk.RIGHT)
        # Seznam úkolů s posuvníkem
        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)
        # Dolní panel: tlačítka akcí
        bottom_frame = tk.Frame(self.root)
        bottom_frame.pack(pady=10, padx=10, fill=tk.X)
        self.done_button = tk.Button(bottom_frame, text="✅ Hotovo", command=self.mark_done)
        self.done_button.pack(side=tk.LEFT, padx=5)
        self.delete_button = tk.Button(bottom_frame, text="🗑 Odstranit", command=self.delete_task)
        self.delete_button.pack(side=tk.LEFT, padx=5)
        self.exit_button = tk.Button(bottom_frame, text="Konec", command=self.root.quit)
        self.exit_button.pack(side=tk.RIGHT, padx=5)

    def refresh_task_list(self):
        """Aktualizuje zobrazení seznamu úkolů v rozhraní."""
        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)

Metoda refresh_task_list implementuje operaci Read, zobrazující aktuální stav dat. Symboly ✓ a ○ vizualizují stav dokončení.

Implementace CRUD operací v rozhraní

Přidáme do třídy metody, které zpracovávají akce uživatele, provádějící odpovídající CRUD operace.

Create: přidání nového úkolu

    def add_task(self):
        """Přidá nový úkol (Create)."""
        text = self.entry.get().strip()
        if not text:
            messagebox.showwarning("Varování", "Zadejte text úkolu")
            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("Úspěch", f"Úkol přidán (ID: {next_id})")

Update: označení úkolu jako hotovo

    def mark_done(self):
        """Označí vybraný úkol jako hotový (Update)."""
        selection = self.task_listbox.curselection()
        if not selection:
            messagebox.showwarning("Varování", "Vyberte úkol")
            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("Informace", "Úkol je již hotový")
                else:
                    task["completed"] = True
                    save_tasks(self.tasks)
                    self.refresh_task_list()
                    messagebox.showinfo("Úspěch", f"Úkol #{task_id} označen jako hotový")
                return

Delete: odstranění úkolu

    def delete_task(self):
        """Odstraní vybraný úkol (Delete)."""
        selection = self.task_listbox.curselection()
        if not selection:
            messagebox.showwarning("Varování", "Vyberte úkol")
            return
        index = selection[0]
        task_id = self.tasks[index]["id"]
        task_text = self.tasks[index]["text"]
        if messagebox.askyesno("Potvrzení", f"Odstranit úkol #{task_id} \"{task_text}\"?"):
            del self.tasks[index]
            save_tasks(self.tasks)
            self.refresh_task_list()
            messagebox.showinfo("Úspěch", f"Úkol #{task_id} odstraněn")

Každá metoda zahrnuje validaci vstupu, změnu dat v paměti, uložení do souboru a aktualizaci rozhraní. Použití messagebox zlepšuje UX, poskytuje zpětnou vazbu.

Google AdInline article slot

Sestavení a spuštění aplikace

Pro dokončení projektu spojíme všechny komponenty v jednom souboru a přidáme vstupní bod.

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

Spusťte skript příkazem python app.py. Aplikace otevře okno, kde můžete testovat všechny CRUD operace. Data budou uložena mezi sezeními v souboru tasks.json.

Co je důležité

  • CRUD je základ: Vzor Create, Read, Update, Delete je základní pro většinu aplikací pracujících s daty.
  • JSON pro ukládání: Použití JSON souborů je jednoduchý a efektivní způsob ukládání dat pro malé projekty, které nevyžadují plnohodnotnou databázi.
  • Tkinter pro GUI: Knihovna Tkinter umožňuje rychle vytvářet multiplatformní desktopová rozhraní bez externích závislostí.
  • Struktura kódu: Jasné oddělení na datový model (práce s JSON), prezentaci (Tkinter) a logiku aplikace (třída TodoApp) zlepšuje udržovatelnost kódu.
  • Zpracování chyb: Implementace zahrnuje kontroly správnosti vstupu a zpracování výjimek (např. poškozený JSON soubor).

Další rozvoj projektu

Tento správce úkolů lze rozšířit následujícími způsoby:

  • Přidání kategorií úkolů s možností filtrování.
  • Implementace termínů s použitím modulu datetime a barevnou indikací.
  • Export dat do formátů CSV nebo Excel pro reportování.
  • Integrace s databázemi (SQLite, PostgreSQL) pro spolehlivější ukládání.
  • Vytvoření webové verze s využitím Flask nebo Django, což umožní procvičit stejné CRUD operace v jiném kontextu.

Taký přístup demonstruje, jak se základní koncepty programování aplikují v reálných projektech, poskytuje pevný základ pro studium složitějších témat.

— Editorial Team

Advertisement 728x90

Číst dál