Python Tkinter - 8. Tkinter 추천 프로젝트

2025. 2. 28. 14:37프로그래밍 언어/Python

8. Tkinter 추천 프로젝트: 최종 정리 및 개선 사항 반영

이 문서는 Tkinter를 활용한 추천 프로젝트 3가지(데이터 시각화 대시보드, 채팅 애플리케이션, 포모도로 타이머) 에 대한 개선 사항을 반영하여
보다 실용적이고 안정적인 애플리케이션을 개발할 수 있도록 구성되었습니다.

🚀 최신 개선점
import 문 정리 (불필요한 모듈 제거)
GUI 친화적인 예외 처리 추가 (메시지 박스 활용)
UX 개선: 시각적 피드백 추가 (포모도로 타이머에 색상 변경 기능 추가)
객체 지향 프로그래밍(OOP) 적용 (구조적 코드 작성)


1. 데이터 시각화 대시보드

Tkinter와 Matplotlib, Pandas를 활용하여 실시간 데이터 시각화 대시보드를 제작합니다.
데이터 분석, 그래프 출력, GUI 업데이트를 포함하여 실무에서도 많이 사용되는 기능을 익힐 수 있습니다.

📌 주요 기능

CSV 파일 불러오기
Matplotlib 그래프를 Tkinter에서 표시
기존 그래프 삭제 후 새 데이터 로드
GUI 기반 오류 메시지 출력

💻 개선된 코드 예제: 데이터 시각화 대시보드

import tkinter as tk
from tkinter import filedialog, messagebox
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

class DataDashboard:
    def __init__(self, root):
        self.root = root
        self.root.title("데이터 시각화 대시보드")

        self.btn = tk.Button(root, text="CSV 파일 불러오기", command=self.load_data)
        self.btn.pack()

        self.canvas_frame = tk.Frame(root)
        self.canvas_frame.pack()

        self.canvas = None  

    def load_data(self):
        file_path = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv")])
        if file_path:
            try:
                df = pd.read_csv(file_path)
                if "날짜" not in df.columns or "값" not in df.columns:
                    messagebox.showerror("오류", "CSV 파일 형식을 확인하세요.\n'날짜' 및 '값' 열이 필요합니다.")
                    return
                self.plot_graph(df)
            except Exception as e:
                messagebox.showerror("파일 오류", f"CSV 파일을 불러오는 중 오류가 발생했습니다.\n{e}")

    def plot_graph(self, df):
        if self.canvas:
            self.canvas.get_tk_widget().destroy()  

        fig, ax = plt.subplots(figsize=(5, 4))
        ax.plot(df["날짜"], df["값"], marker="o", linestyle="-")
        ax.set_title("데이터 시각화")

        self.canvas = FigureCanvasTkAgg(fig, master=self.canvas_frame)
        self.canvas.draw()
        self.canvas.get_tk_widget().pack()

root = tk.Tk()
app = DataDashboard(root)
root.mainloop()

GUI 기반 오류 메시지 출력 추가
기존 그래프 삭제 후 새 그래프 표시
객체 지향 프로그래밍(OOP) 적용


2. 채팅 애플리케이션

Tkinter와 소켓 프로그래밍을 활용하여 TCP 기반 채팅 애플리케이션을 제작합니다.
이 프로젝트를 통해 네트워크 통신, 멀티스레딩, UI 업데이트를 학습할 수 있습니다.

📌 주요 기능

TCP 소켓을 이용한 클라이언트-서버 메시지 송수신
멀티스레딩을 활용한 실시간 메시지 업데이트
GUI 기반의 메시지 입력 및 표시 기능
서버 연결 실패 시 사용자 안내 메시지 추가

💻 개선된 코드 예제: 채팅 클라이언트

import tkinter as tk
import socket
import threading

class ChatClient:
    def __init__(self, root):
        self.root = root
        self.root.title("Tkinter 채팅 클라이언트")

        self.chat_list = tk.Listbox(root, height=15, width=50)
        self.chat_list.pack()

        self.entry = tk.Entry(root, width=40)
        self.entry.pack(side=tk.LEFT)

        self.send_btn = tk.Button(root, text="전송", command=self.send_message)
        self.send_btn.pack(side=tk.RIGHT)

        self.client_socket = None  
        self.connect_to_server()

    def connect_to_server(self):
        try:
            self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.client_socket.connect(("localhost", 12345))
            threading.Thread(target=self.receive_messages, daemon=True).start()
        except Exception as e:
            self.chat_list.insert(tk.END, f"서버 연결 실패: {e}")
            self.client_socket = None  

    def receive_messages(self):
        while True:
            try:
                msg = self.client_socket.recv(1024).decode("utf-8")
                if not msg:
                    break
                self.chat_list.insert(tk.END, msg)
            except Exception as e:
                print("연결 오류:", e)
                break

    def send_message(self):
        msg = self.entry.get()
        if msg and self.client_socket:
            try:
                self.client_socket.send(msg.encode("utf-8"))
                self.entry.delete(0, tk.END)
            except Exception as e:
                print("전송 오류:", e)

    def on_closing(self):
        if self.client_socket:
            self.client_socket.close()
        self.root.destroy()

root = tk.Tk()
app = ChatClient(root)
root.protocol("WM_DELETE_WINDOW", app.on_closing)  
root.mainloop()

서버 연결 실패 시 사용자 안내 메시지 추가
객체 지향 구조로 코드 정리하여 유지보수 용이


3. 포모도로 타이머 앱

Tkinter를 활용하여 포모도로 타이머(Pomodoro Timer) 를 제작합니다.
UX 개선을 위해 작업/휴식 모드 변경 시 색상이 변경되도록 개선하였습니다.

📌 주요 기능

25분 집중 + 5분 휴식 루틴 실행
남은 시간 실시간 업데이트
타이머 완료 후 자동으로 휴식 모드로 전환
작업/휴식 모드 시 배경색 변경 (UX 개선)

💻 개선된 코드 예제: 포모도로 타이머

import tkinter as tk

class PomodoroTimer:
    def __init__(self, root):
        self.root = root
        self.root.title("포모도로 타이머")

        self.work_time = 25 * 60  
        self.break_time = 5 * 60  
        self.time_left = self.work_time
        self.running = False
        self.is_work_time = True  

        self.label = tk.Label(root, text="25:00", font=("Arial", 30))
        self.label.pack()

        self.start_button = tk.Button(root, text="시작", command=self.start_timer)
        self.start_button.pack()

        self.reset_button = tk.Button(root, text="초기화", command=self.reset_timer)
        self.reset_button.pack()

        self.update_background()

    def start_timer(self):
        if not self.running:
            self.running = True
            self.count_down()

    def count_down(self):
        if self.time_left > 0:
            mins, secs = divmod(self.time_left, 60)
            self.label.config(text=f"{mins:02}:{secs:02}")
            self.time_left -= 1
            self.root.after(1000, self.count_down)
        else:
            self.running = False
            self.switch_mode()

    def switch_mode(self):
        self.is_work_time = not self.is_work_time
        self.time_left = self.work_time if self.is_work_time else self.break_time
        self.update_background()
        self.start_timer()

    def reset_timer(self):
        self.running = False
        self.time_left = self.work_time
        self.is_work_time = True
        self.label.config(text="25:00")
        self.update_background()

    def update_background(self):
        color = "lightgreen" if self.is_work_time else "lightblue"
        self.root.configure(bg=color)

root = tk.Tk()
PomodoroTimer(root)
root.mainloop()

작업/휴식 모드 변경 시 색상이 자동 변경됨 (UX 개선)