구현
파이썬으로 그림판 만들기 (5단계: 지우개)
cs newbie
2025. 4. 16. 15:17
▣ 5단계: 지우개 기능과 실행 취소 기능 추가
✔ 목표
- 지우개 버튼을 누르면 배경색(흰색)으로 선을 그려 지우는 효과
- 지우개도 선 굵기 조절 슬라이더에 반응
- `Ctrl + Z` 키를 누르면 마지막으로 그린 선을 되돌릴 수 있음 (실행 취소)
✔ 코드
import tkinter as tk
from tkinter import colorchooser
# ============================
# 드로잉 함수들
# ============================
def start_draw(event):
"""
마우스를 누를 때 호출됨.
현재 좌표 저장 및 새로운 선 묶음(stroke) 리스트 시작.
"""
global last_x, last_y, current_stroke
last_x, last_y = event.x, event.y
current_stroke = [] # 새로운 stroke 시작
def draw(event):
"""
마우스를 누른 채 이동할 때 호출됨.
이전 좌표부터 현재 좌표까지 선을 그리고, 해당 선의 ID를 저장.
"""
global last_x, last_y
color = current_color.get()
width = brush_size.get()
line = canvas.create_line(last_x, last_y, event.x, event.y,
fill=color, width=width, capstyle=tk.ROUND, smooth=True)
current_stroke.append(line) # 현재 stroke에 선 ID 추가
last_x, last_y = event.x, event.y
def end_draw(event):
"""
마우스를 뗄 때 호출됨.
하나의 stroke가 완성되면 전체 stroke 리스트에 저장.
"""
if current_stroke:
drawn_lines.append(current_stroke)
# ============================
# 슬라이더 ↔ 드롭다운 연동
# ============================
def update_from_slider(value):
dropdown_var.set(int(value))
def update_from_dropdown(*args):
brush_size.set(dropdown_var.get())
# ============================
# 색상 선택 함수
# ============================
def choose_color():
color_code = colorchooser.askcolor(title="선 색상 선택")
if color_code[1]:
current_color.set(color_code[1])
color_preview.config(bg=color_code[1])
# ============================
# 지우개 기능
# ============================
def use_eraser():
"""
지우개 버튼 클릭 시 호출됨. 현재 색상을 흰색으로 설정.
실제로는 흰색 선을 그려 지우는 효과.
"""
current_color.set("white")
color_preview.config(bg="white")
# ============================
# 실행 취소 기능
# ============================
def undo(event=None):
"""
Ctrl+Z 입력 시 호출됨.
마지막 stroke(선들의 묶음)를 캔버스에서 삭제.
"""
if drawn_lines:
last_stroke = drawn_lines.pop()
for line_id in last_stroke:
canvas.delete(line_id)
# ============================
# GUI 생성
# ============================
root = tk.Tk()
root.title("그림판")
# 전역 변수들 초기화
current_color = tk.StringVar(value="black") # 현재 선택된 색상
brush_size = tk.IntVar(value=2) # 브러시 굵기
current_stroke = [] # 현재 그리고 있는 stroke
drawn_lines = [] # 그려진 stroke들의 리스트
# 단축키 등록
root.bind("<Control-z>", undo)
# ▶ 상단 툴바 프레임
top_frame = tk.Frame(root)
top_frame.pack(side="top", fill="x", pady=5, padx=10)
# ▶ 왼쪽 도구 그룹: 선 굵기 설정 (슬라이더 + 드롭다운)
left_tool_frame = tk.Frame(top_frame)
left_tool_frame.pack(side="left")
slider = tk.Scale(left_tool_frame, from_=1, to=20, orient="horizontal",
variable=brush_size, label="선 굵기",
command=update_from_slider)
slider.pack(side="left", padx=5)
dropdown_var = tk.IntVar(value=2)
dropdown_options = [1, 2, 4, 8, 12, 16, 20]
dropdown_menu = tk.OptionMenu(left_tool_frame, dropdown_var, *dropdown_options)
dropdown_menu.config(width=6)
dropdown_var.trace_add("write", update_from_dropdown)
dropdown_menu.pack(side="left", padx=5)
# ▶ 오른쪽 도구 그룹: 색상 선택, 지우개 버튼
right_tool_frame = tk.Frame(top_frame)
right_tool_frame.pack(side="right")
color_btn = tk.Button(right_tool_frame, text="색상 선택", command=choose_color)
color_btn.pack(side="left", padx=5)
color_preview = tk.Label(right_tool_frame, bg=current_color.get(), width=3,
relief="solid", borderwidth=1, cursor="hand2")
color_preview.pack(side="left", padx=3)
color_preview.bind("<Button-1>", lambda e: choose_color())
eraser_btn = tk.Button(right_tool_frame, text="지우개", command=use_eraser)
eraser_btn.pack(side="left", padx=5)
# ▶ 캔버스 (그림판 본체)
canvas = tk.Canvas(root, bg="white", width=800, height=600)
canvas.pack(fill="both", expand=True)
# 마우스 이벤트 바인딩
canvas.bind("<Button-1>", start_draw) # 그리기 시작
canvas.bind("<B1-Motion>", draw) # 마우스 이동 중 그리기
canvas.bind("<ButtonRelease-1>", end_draw) # 그리기 종료
root.mainloop()
✔ 설명 요약
- 지우개는 그냥 "배경색(white)으로 선을 그리는 것"입니다.
- 지우개 굵기 = 브러시 굵기와 동일한 슬라이더로 조절됩니다.
- `Ctrl + Z` 입력 시 가장 마지막 선을 삭제하여 **실행 취소** 구현
- (참고) 투명하게 지우는 기능은 Tkinter 기본 canvas로는 불가능합니다.