홈으로 돌아가기

Python에서 CRUD: Tkinter와 JSON을 사용한 작업 관리자 만들기

데스크톱 작업 관리자를 만들어 Python에서 CRUD 작업 구현하는 실전 가이드. 기사는 그래픽 인터페이스 구축을 위한 Tkinter 작업, 데이터 저장을 위한 JSON 사용, 객체 지향 프로그래밍 기초를 다룹니다.

Python에서 CRUD 애플리케이션 만들기: 처음부터 작업 관리자
Advertisement 728x90

# 실습 CRUD 가이드: Python과 Tkinter로 할 일 관리자 만들기

CRUD(Create, Read, Update, Delete)는 데이터 작업의 핵심 패턴입니다. 이 가이드에서는 Python, Tkinter, JSON 데이터 저장을 사용해 데스크톱 할 일 관리자를 직접 만들어보며 실습합니다. OOP 기초, 파일 처리, GUI 개발을 다지기 딱 좋은 프로젝트입니다.

앱 구조와 환경 설정

앱은 단일 app.py 파일로 구성합니다. 데이터 저장은 JSON을 사용해 간단하게 구현합니다. 각 할 일은 id(고유 식별자), text(설명), completed(완료 상태)를 가진 딕셔너리입니다. 모든 할 일은 리스트에 저장되며 tasks.json으로 직렬화됩니다.

Python 3.6 이상이 설치되어 있는지 확인하세요. Tkinter는 기본 내장되어 있어 별도 설치가 필요 없습니다. 새 프로젝트 폴더를 만들고 IDE에서 엽니다.

Google AdInline article slot

데이터 모델과 JSON 처리

먼저 Read와 Update CRUD 작업의 기반이 되는 데이터 로드/저장 함수를 구현합니다.

import json
import os

TASKS_FILE = "tasks.json"

def load_tasks():
    """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):
    """할 일 리스트를 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):
    """새 할 일의 다음 고유 ID 생성."""
    if not tasks:
        return 1
    return max(task["id"] for task in tasks) + 1

주요 특징:

  • load_tasks는 파일 누락이나 손상 시 안전하게 처리합니다.
  • json.dumpensure_ascii=False로 유니코드 제대로 지원합니다.
  • indent=2로 JSON 가독성 높입니다.

Tkinter로 GUI 구축

메인 윈도우와 위젯을 관리하는 TodoApp 클래스를 만듭니다. 인터페이스는 다음과 같습니다:

Google AdInline article slot
  • 새 할 일 입력 필드.
  • 모든 할 일 표시 리스트박스.
  • 제어 버튼: 추가, 완료 표시, 삭제.
import tkinter as tk
from tkinter import messagebox

class TodoApp:
    def __init__(self, root):
        self.root = root
        self.root.title("할 일 관리자")
        self.root.geometry("500x400")
        self.root.resizable(False, False)
        self.tasks = load_tasks()
        self.create_widgets()
        self.refresh_task_list()

    def create_widgets(self):
        """모든 UI 요소 설정."""
        # 상단 패널: 입력과 추가 버튼
        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="➕ 추가", command=self.add_task)
        self.add_button.pack(side=tk.RIGHT)
        # 할 일 리스트와 스크롤바
        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)
        # 하단 패널: 동작 버튼
        bottom_frame = tk.Frame(self.root)
        bottom_frame.pack(pady=10, padx=10, fill=tk.X)
        self.done_button = tk.Button(bottom_frame, text="✅ 완료", command=self.mark_done)
        self.done_button.pack(side=tk.LEFT, padx=5)
        self.delete_button = tk.Button(bottom_frame, text="🗑 삭제", command=self.delete_task)
        self.delete_button.pack(side=tk.LEFT, padx=5)
        self.exit_button = tk.Button(bottom_frame, text="종료", command=self.root.quit)
        self.exit_button.pack(side=tk.RIGHT, padx=5)

    def refresh_task_list(self):
        """할 일 리스트 표시 새로고침."""
        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는 Read 작업을 처리하며 현재 데이터 상태를 보여줍니다. 체크 표시(✓/○)로 완료 상태를 시각화합니다.

CRUD 작업 구현

클래스에 사용자 동작 메서드를 추가합니다. 각 메서드는 CRUD 작업과 연결됩니다.

Create: 새 할 일 추가

    def add_task(self):
        """새 할 일 추가(Create)."""
        text = self.entry.get().strip()
        if not text:
            messagebox.showwarning("경고", "할 일 내용을 입력하세요")
            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("성공", f"할 일 추가됨 (ID: {next_id})")

Update: 할 일 완료 표시

    def mark_done(self):
        """선택한 할 일 완료 표시(Update)."""
        selection = self.task_listbox.curselection()
        if not selection:
            messagebox.showwarning("경고", "할 일을 선택하세요")
            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("알림", "이미 완료된 할 일입니다")
                else:
                    task["completed"] = True
                    save_tasks(self.tasks)
                    self.refresh_task_list()
                    messagebox.showinfo("성공", f"할 일 #{task_id} 완료로 표시됨")
                return

Delete: 할 일 삭제

    def delete_task(self):
        """선택한 할 일 삭제(Delete)."""
        selection = self.task_listbox.curselection()
        if not selection:
            messagebox.showwarning("경고", "할 일을 선택하세요")
            return
        index = selection[0]
        task_id = self.tasks[index]["id"]
        task_text = self.tasks[index]["text"]
        if messagebox.askyesno("확인", f"할 일 #{task_id} \"{task_text}\"을 삭제하시겠습니까?"):
            del self.tasks[index]
            save_tasks(self.tasks)
            self.refresh_task_list()
            messagebox.showinfo("성공", f"할 일 #{task_id} 삭제됨")

각 메서드는 입력 검증, 메모리 내 데이터 업데이트, 파일 저장, UI 새로고침을 수행합니다. 메시지박스로 사용자에게 명확한 피드백을 줍니다.

Google AdInline article slot

앱 조립 및 실행

모든 것을 하나의 파일에 모으고 메인 진입점을 추가합니다.

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

python app.py로 실행하세요. 모든 CRUD 작업을 테스트해보세요—앱은 세션 간 tasks.json에 데이터를 저장합니다.

주요 요점

  • CRUD 기초: Create, Read, Update, Delete는 대부분의 데이터 중심 앱 동력입니다.
  • JSON 저장: 작은 프로젝트에 이상적—데이터베이스 불필요.
  • Tkinter GUI: 의존성 없이 빠른 크로스플랫폼 데스크톱 UI.
  • 깔끔한 코드 구조: 데이터 모델(JSON), 뷰(Tkinter), 로직(TodoApp) 분리로 유지보수 용이.
  • 에러 처리: 입력 검증과 JSON 오류 등 문제 포착.

다음 단계

할 일 관리자를 확장해보세요:

  • 할 일 카테고리와 필터링.
  • datetime 사용 마감일과 색상 구분.
  • CSV나 Excel 내보내기.
  • 데이터베이스 연동 (SQLite, PostgreSQL).
  • 웹 버전 Flask나 Django로.

이 프로젝트는 핵심 프로그래밍 개념이 실제 앱에 어떻게 적용되는지 보여주며, 고급 주제의 튼튼한 기반을 마련합니다.

— Editorial Team

Advertisement 728x90

다음 읽기