어제 이어서 tkinter
https://076923.github.io/posts/Python-tkinter-8/
Python tkinter 강좌 : 제 8강 - Menu
Menu(메뉴)
076923.github.io
8강 Menu
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x480+100+100")
window.resizable(False, False)
def close():
window.quit()
window.destroy()
menubar=tkinter.Menu(window)
menu_1=tkinter.Menu(menubar, tearoff=0)
menu_1.add_command(label="하위 메뉴 1-1")
menu_1.add_command(label="하위 메뉴 1-2")
menu_1.add_separator()
menu_1.add_command(label="하위 메뉴 1-3", command=close)
menubar.add_cascade(label="상위 메뉴 1", menu=menu_1)
menu_2=tkinter.Menu(menubar, tearoff=0, selectcolor="red")
menu_2.add_radiobutton(label="하위 메뉴 2-1", state="disabled")
menu_2.add_radiobutton(label="하위 메뉴 2-2")
menu_2.add_radiobutton(label="하위 메뉴 2-3")
menubar.add_cascade(label="상위 메뉴 2", menu=menu_2)
menu_3=tkinter.Menu(menubar, tearoff=0)
menu_3.add_checkbutton(label="하위 메뉴 3-1")
menu_3.add_checkbutton(label="하위 메뉴 3-2")
menubar.add_cascade(label="상위 메뉴 3", menu=menu_3)
window.config(menu=menubar)
window.mainloop()
print("Window Close")

메뉴 이름=tkinter.Menu(윈도우 창)을 사용하여 해당 윈도우 창에 메뉴를 사용
상위 메뉴 이름=tkinter.Menu(메뉴 이름, 매개변수1, 매개변수2, 매개변수3, ...)을 사용하여 해당 메뉴창에 표시할 상위 메뉴의 속성을 설정
매개변수를 사용하여 상위 메뉴의 속성을 설정
window.quit()는 위젯이 유지된 채 window.mainloop() 이후의 코드를 실행(눈에 보이는 것만 삭제)
window.destroy()는 위젯을 파괴하고 window.mainloop() 이후의 코드를 실행(삭제)
menu_1=tkinter.Menu(menubar, tearoff=1)
tearoff 0->1

9강 Menubutton
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
menubutton=tkinter.Menubutton(window,text="메뉴 메뉴 버튼", relief="raised", direction="right")# 버튼 방향 R
#메뉴버튼 : 클릭하면 메뉴 나타나는 버튼
menubutton.pack()
menu1=tkinter.Menu(menubutton, tearoff=0)
menu1.add_command(label="하위메뉴-1")
menu1.add_separator()
menu1.add_command(label="하위메뉴-2")
menu1.add_command(label="하위메뉴-3")
menubutton["menu"]=menu1
#menubutton 객체의 menu 속성에 menu 인스턴스 할당
#window.config(menu=menubar)
window.mainloop()

10강 pack
pack()이 선언된 순서대로 올라감
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
b1=tkinter.Button(window, text="top")
b1_1=tkinter.Button(window, text="top-1")
b2=tkinter.Button(window, text="bottom")
b2_1=tkinter.Button(window, text="bottom-1")
b3=tkinter.Button(window, text="left")
b3_1=tkinter.Button(window, text="left-1")
b4=tkinter.Button(window, text="right")
b4_1=tkinter.Button(window, text="right-1")
b5=tkinter.Button(window, text="center", bg="white")
b1.pack(side="top")
b1_1.pack(side="top", fill="x")
b2.pack(side="bottom")
b2_1.pack(side="bottom", anchor="e")
b3.pack(side="left")
b3_1.pack(side="left", fill="y")
b4.pack(side="right")
b4_1.pack(side="right", anchor="s")
b5.pack(expand=True, fill="both")
window.mainloop()

배치 순서 그대로 올라감
11강 grid
grid로 위젯 배치
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
b1=tkinter.Button(window, text="(0, 0)")
b2=tkinter.Button(window, text="(0, 1)", width=20)
b3=tkinter.Button(window, text="(0, 2)")
b4=tkinter.Button(window, text="(1, 0)")
b5=tkinter.Button(window, text="(1, 1)")
b6=tkinter.Button(window, text="(1, 3)")
b7=tkinter.Button(window, text="(2, 1)")
b8=tkinter.Button(window, text="(2, 2)")
b9=tkinter.Button(window, text="(2, 4)")
b1.grid(row=0, column=0)
b2.grid(row=0, column=1)
b3.grid(row=0, column=2)
b4.grid(row=1, column=0, rowspan=2)
b5.grid(row=1, column=1, columnspan=3)
b6.grid(row=1, column=3)
b7.grid(row=2, column=1, sticky="w")
b8.grid(row=2, column=2)
b9.grid(row=2, column=99)
window.mainloop()

rowspan=2
행 합치기 =>중앙정렬(1,0)
column=99
큰 숫자를 주면 끝으로 자동 정렬
12강 위치배치 place
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
b1=tkinter.Button(window, text="(50, 50)")
b2=tkinter.Button(window, text="(50, 100)")
b3=tkinter.Button(window, text="(100, 150)")
b4=tkinter.Button(window, text="(0, 200)")
b5=tkinter.Button(window, text="(0, 300)")
b6=tkinter.Button(window, text="(0, 300)")
b1.place(x=50, y=50)
b2.place(x=50, y=100, width=50, height=50) #width,height : 버튼 사이즈 지정
b3.place(x=100, y=150, bordermode="inside")
b4.place(x=0, y=200, relwidth=0.5) #부모창 크기에 대비한 위젯 사이즈
b5.place(x=0, y=300, relx=0.5) #창 전체 크기에 대한 상대 비율
b6.place(x=0, y=300, relx=0.5, anchor="s")
window.mainloop()

bordermode: 테두리 포함 여부
계산기 실습
import tkinter as tk
window = tk.Tk()
window.title("계산기")
window.geometry("300x350")
window.resizable(False, False)
expression = ""
def press(value):
global expression
expression += str(value)
display_var.set(expression)
def calculate():
global expression
try:
result = str(eval(expression))
display_var.set(result)
expression = result
except:
display_var.set("Error")
expression = ""
def clear():
global expression
expression = ""
display_var.set("")
display_var = tk.StringVar()
display = tk.Entry(
window,
textvariable=display_var,
font=("Arial", 10),
justify="right",
bd=2,
relief="solid",
)
display.pack(fill="both", ipadx=8, ipady=15, padx=10, pady=10)
btn_frame = tk.Frame(window)
btn_frame.pack(expand=True, fill="both")
buttons = [
("7", 0, 0), ("8", 0, 1), ("9", 0, 2), ("÷", 0, 3),
("4", 1, 0), ("5", 1, 1), ("6", 1, 2), ("×", 1, 3),
("1", 2, 0), ("2", 2, 1), ("3", 2, 2), ("–", 2, 3),
("0", 3, 0), ("", 3, 1), ("=", 3, 2), ("+", 3, 3),
]
for (text, row, col) in buttons:
if text == "":
continue
elif text == "=":
cmd = calculate
else:
cmd = lambda t=text: press(t)
btn = tk.Button(
btn_frame,
text=text,
font=("Arial", 10),
command=cmd
)
btn.grid(row=row, column=col, sticky="nsew", padx=1, pady=1)
clear_btn = tk.Button(
btn_frame,
text="C",
font=("Arial", 10),
command=clear,
anchor="e",
padx=20
)
clear_btn.grid(row=4, column=0, columnspan=3, sticky="nsew", padx=(5, 40), pady=1)
for i in range(4):
btn_frame.columnconfigure(i, weight=1)
for i in range(5):
btn_frame.rowconfigure(i, weight=1)
window.mainloop()

결과 출력 후 입력시 자동 clear
delete키 추가
import tkinter as tk
window = tk.Tk()
window.title("계산기")
window.geometry("300x350")
window.resizable(False, False)
expression = ""
operators = ["+", "–", "×", "÷"]
just_calculated = False
def press(value):
global expression, just_calculated
if just_calculated and value not in operators:
expression = ""
just_calculated = False
if value in operators:
if not expression:
return
if expression[-1] in operators:
expression = expression[:-1]
expression += str(value)
display_var.set(expression)
def calculate():
global expression, just_calculated
try:
expr = expression.replace("×", "*").replace("÷", "/").replace("–", "-")
result = str(eval(expr))
display_var.set(result)
expression = result
just_calculated = True
except:
display_var.set("Error")
expression = ""
just_calculated = False
def clear():
global expression, just_calculated
expression = ""
display_var.set("")
just_calculated = False
def delete():
global expression, just_calculated
if just_calculated:
expression = ""
display_var.set("")
just_calculated = False
return
if expression:
expression = expression[:-1]
display_var.set(expression)
display_var = tk.StringVar()
display = tk.Entry(
window,
textvariable=display_var,
font=("Arial", 10),
justify="right",
bd=2,
relief="solid",
)
display.pack(fill="both", ipadx=8, ipady=15, padx=10, pady=10)
btn_frame = tk.Frame(window)
btn_frame.pack(expand=True, fill="both")
buttons = [
("7", 0, 0), ("8", 0, 1), ("9", 0, 2), ("÷", 0, 3),
("4", 1, 0), ("5", 1, 1), ("6", 1, 2), ("×", 1, 3),
("1", 2, 0), ("2", 2, 1), ("3", 2, 2), ("–", 2, 3),
("0", 3, 0), ("", 3, 1), ("=", 3, 2), ("+", 3, 3),
]
for (text, row, col) in buttons:
if text == "":
continue
elif text == "=":
cmd = calculate
else:
cmd = lambda t=text: press(t)
btn = tk.Button(
btn_frame,
text=text,
font=("Arial", 10),
command=cmd
)
btn.grid(row=row, column=col, sticky="nsew", padx=1, pady=1)
clear_btn = tk.Button(
btn_frame,
text="C",
font=("Arial", 10),
command=clear,
anchor="e",
padx=20
)
delete_btn = tk.Button(
btn_frame,
text="◀",
font=("Arial", 10),
command=delete,
padx=20
)
clear_btn.grid(row=4, column=0, columnspan=3, sticky="nsew", padx=(5, 40), pady=1)
delete_btn.grid(row=4, column=3, columnspan=2, sticky="nsew", padx=1, pady=1)
for i in range(4):
btn_frame.columnconfigure(i, weight=1)
for i in range(5):
btn_frame.rowconfigure(i, weight=1)
window.mainloop()

정답 코드
import tkinter as tk
window = tk.Tk()
entry=tk.Entry(window)
entry.grid(row=0,column=0, columnspan=4)
def button_click(t):
current=entry.get()
entry.delete(0, tk.END)
entry.insert(0, current+str(t))
def calculate():
try:
result=eval(entry.get())
entry.delete(0, tk.END)
entry.insert(0, str(result))
except:
entry.delete(0, tk.END)
entry.insert(0, 'Error')
def clear():
entry.delete(0, tk.END)
buttons = [
("7", 1, 0), ("8", 1, 1), ("9", 1, 2), ("/", 1, 3),
("4", 2, 0), ("5", 2, 1), ("6", 2, 2), ("*", 2, 3),
("1", 3, 0), ("2", 3, 1), ("3", 3, 2), ("-", 3, 3),
("0", 4, 0), (".", 4, 1), ("+", 4, 2)]
for (text, r, c) in buttons:
tk.Button(window, text=text, width=5, height=2, command=lambda t=text:button_click(t)).grid(row=r, column=c)
tk.Button(window, text="=", width=5, height=2, command=calculate).grid(row=4, column=3)
tk.Button(window, text="C", width=10, height=2, command=clear).grid(row=5, column=0, columnspan=4)
window.mainloop()

13강 Frame
Frame을 이용하여 다른 위젯들을 포함하기 위한 프레임을 생성할 수 있음
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
frame1=tkinter.Frame(window, relief="solid", bd=2)
frame1.pack(side="left", fill="both", expand=True)
frame2=tkinter.Frame(window, relief="solid", bd=2)
frame2.pack(side="right", fill="both", expand=True)
button1=tkinter.Button(frame1, text="프레임1")
button1.pack(side="right")
button2=tkinter.Button(frame2, text="프레임2")
button2.pack(side="left")
window.mainloop()

import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
frame1=tkinter.Frame(window, relief="solid", bd=2)
frame1.pack(side="left", fill="both", expand=True)
frame2=tkinter.Frame(window, relief="solid", bd=2)
frame2.pack(side="right", fill="both", expand=True)
button1=tkinter.Button(frame2, text="프레임1")
button1.pack(side="right")
button2=tkinter.Button(frame2, text="프레임2")
button2.pack(side="left")
window.mainloop()

import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
frame1=tkinter.Frame(window, relief="solid", bd=2, width=500)
frame1.pack(side="left", fill="both", expand=True)
frame2=tkinter.Frame(window, relief="solid", bd=2)
frame2.pack(side="right", fill="both", expand=True)
# button1=tkinter.Button(frame1, text="프레임1")
# button1.pack(side="right")
button2=tkinter.Button(frame2, text="프레임2")
button2.pack(side="left")
window.mainloop()

import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
frame1=tkinter.Frame(window, relief="solid", bd=2, width=500)
frame1.pack(side="left", fill="both", expand=True)
frame2=tkinter.Frame(window, relief="solid", bd=2)
frame2.pack(side="right", fill="both", expand=True)
frame3=tkinter.Frame(window, relief="solid", bd=2)
frame3.pack(side="right", fill="both", expand=True)
# button1=tkinter.Button(frame1, text="프레임1")
# button1.pack(side="right")
#
# button2=tkinter.Button(frame2, text="프레임2")
# button2.pack(side="left")
window.mainloop()

import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
frame1=tkinter.Frame(window, relief="solid", bd=2, width=500)
frame1.pack(side="left", fill="both", expand=True)
frame2=tkinter.Frame(window, relief="solid", bd=2)
frame2.pack(side="right", fill="both", expand=True)
frame3=tkinter.Frame(window, relief="solid", bd=2, width=20)
frame3.pack(side="right", fill="both", expand=True)
button1=tkinter.Button(frame1, text="프레임1")
button1.pack(side="right")
button2=tkinter.Button(frame2, text="프레임2")
button2.pack(side="left")
window.mainloop()

14강 Message
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
message=tkinter.Message(window, text="메세지입니다.", width=100, relief="solid")
message.pack()
window.mainloop()

15강 Canvas
Canvas을 이용하여 선, 다각형, 원등을 그리기 위한 캔버스을 생성
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
canvas=tkinter.Canvas(window, relief="solid", bd=2)
line=canvas.create_line(10, 10, 20, 20, 20, 130, 30, 140, fill="red")
polygon=canvas.create_polygon(50, 50, 170, 170, 100, 170, outline="yellow")
oval=canvas.create_oval(100, 200, 150, 250, fill="blue", width=3)
arc=canvas.create_arc(100, 100, 300, 300, start=0, extent=150, fill='red')
canvas.pack()
window.mainloop()

line=canvas.create_line(10, 10, 20, 20, 20, 130, 30, 140, fill="red")
polygon=canvas.create_polygon(50, 50, 170, 170, 100, 170, outline="yellow")
oval=canvas.create_oval(50, 50, 50, 50, fill="blue", width=3)
arc=canvas.create_arc(0, 0, 200, 200, start=90, extent=150, fill='red')

canvas=>나중에 로봇 이동 경로나 장애물 맵 만들 때 활용할지도
16강 Scrollbar
Scrollbar을 이용하여 위젯에 스크롤을 적용하기 위한 스크롤바를 생성
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
frame=tkinter.Frame(window)
scrollbar=tkinter.Scrollbar(frame)
scrollbar.pack(side="right", fill="y")
#side는 부모 요소 기준 -> frame의 오른쪽에 붙인다.
#fill = y t축방향으로 꽉 채운다.
listbox=tkinter.Listbox(frame, yscrollcommand = scrollbar.set)
#scrollbar.set은 리스트박스를 움직이면 스크롤바 막대도 같이 연동
for line in range(1,1001):
listbox.insert(line, str(line) + "/1000")
listbox.pack(side="left")#부모 frame의 좌측에 붙임
scrollbar["command"]=listbox.yview
#스크롤바 막대를 움직이려면 리스트 박스의 화면 y축을 움직여라
frame.pack()
window.mainloop()

17강 Scale
Scale을 이용하여 값을 설정하기 위한 수치 조정 바를 생성
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
def select(self):
value="값 : "+str(scale.get())
label.config(text=value)
var=tkinter.IntVar()#tkinter 정수 변수 생성
scale=tkinter.Scale(window, variable=var, command=select, orient="horizontal", showvalue=False, tickinterval=50, to=500, length=300)
scale.pack()
label=tkinter.Label(window, text="값 : 0")
label.pack()
window.mainloop()

18강 Text
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(True, True)
text=tkinter.Text(window)
text.insert(tkinter.CURRENT, "안녕하세요.\n")#tkinter.CURRENT : 현재위치(포커스잡힌부분)
text.insert("current", "반습니다.")
text.insert(2.1, "갑")#2번째 줄에 1번째 인덱스
text.pack()
text.tag_add("강조", "1.0", "1.6")#첫번째 줄 0번째 글자부터 6번째 까지
text.tag_config("강조", background="yellow")#배경을 노란색
text.tag_remove("강조", "1.1", "1.2")#첫줄 1번째부터 2번째까지 삭제
window.mainloop()

19강 LabelFrame
import tkinter
window = tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(True, True)
def check():
label.config(text=RadioVariety_1.get())
labelframe = tkinter.LabelFrame(window, text="플랫폼 선택")
labelframe.pack()
RadioVariety_1 = tkinter.StringVar()
RadioVariety_1.set("미선택")
radio1 = tkinter.Radiobutton(labelframe, text="Python", value="가능", variable=RadioVariety_1, command=check)
radio1.pack()
radio2 = tkinter.Radiobutton(labelframe, text="C/C++", value="부분 가능", variable=RadioVariety_1, command=check)
radio2.pack()
radio3 = tkinter.Radiobutton(labelframe, text="JSON", value="불가능", variable=RadioVariety_1, command=check)
radio3.pack()
label = tkinter.Label(labelframe, text="None")
label.pack()
window.mainloop()

20강 PanedWindow
다른 위젯들을 포함하고 구역을 나눌 수 있는 내부 윈도우를 생성
import tkinter
window = tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(True, True)
panedwindow1 = tkinter.PanedWindow(relief="raised", bd=2)
panedwindow1.pack(expand=True)
left = tkinter.Label(panedwindow1, text="내부윈도우-1 (좌측)")
panedwindow1.add(left)
panedwindow2 = tkinter.PanedWindow(panedwindow1, orient="vertical", relief="groove", bd=3)
panedwindow1.add(panedwindow2)
right = tkinter.Label(panedwindow1, text="내부윈도우-2 (우측)")
panedwindow1.add(right)
top = tkinter.Label(panedwindow2, text="내부윈도우-3 (상단)")
panedwindow2.add(top)
bottom = tkinter.Label(panedwindow2, text="내부윈도우-4 (하단)")
panedwindow2.add(bottom)
window.mainloop()

21강 Font
import tkinter
import tkinter.font
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(True, True)
font=tkinter.font.Font(family="맑은 고딕", size=20, slant="italic")
label=tkinter.Label(window, text="파이썬 3.6", font=font)
label.pack()
window.mainloop()

22강 PhotoImage
tkinter.PhotoImage(경로)을 사용하여 위젯에 표시할 이미지의 경로를 설정
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(True, True)
image=tkinter.PhotoImage(file="a.png")
label=tkinter.Label(window, image=image)
label.pack()
window.mainloop()

이미지 축소, 확대 추가
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("2500x2000+100+100")
window.resizable(True, True)
image=tkinter.PhotoImage(file="output.png")#png/gif/pgm
#jpg, jpeg => PhotoImage로 import 불가, PIL 라이브러리로 jpg 불러올 수 있다.
# small_image=image.subsample(4, 4) #이미지 축소 힘수
# large_image=image.zoom(2, 2) #이미지 확대 함수
label=tkinter.Label(window, image=small_image)
label.pack()
window.mainloop()
23강 Bind
이벤트 실행, Bind를 이용하여 위젯들의 이벤트와 실행할 함수를 설정
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(True, True)
width=1
def drawing(event):
print(event)
if width>0: #양수라면
x1=event.x-1 #event 매개변수에는 자동으로 마우스 이벤트 객체가 전달된다
#event는 obj
#x는 속성
y1=event.y-1
x2=event.x+1
y2=event.y+1
canvas.create_oval(x1, y1, x2, y2, fill="blue", width=width)
def scroll(event):
global width
if event.delta==120: #위로 굴릴 때
width+=1
if event.delta==-120: #아래로 굴릴 때
width-=1
label.config(text=str(width))
canvas=tkinter.Canvas(window, relief="solid", bd=2)
canvas.pack(expand=True, fill="both")
canvas.bind("<B1-Motion>", drawing) #drawing 함수는 event 매개변수를 요청하지만 절달하지 않음
canvas.bind("<MouseWheel>", scroll) #scroll 함수도 event 매개변수에 값을 요청하지만 전달하는 값 없음
label=tkinter.Label(window, text=str(width))
label.pack()
window.mainloop()

색상 추가 + 반전
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(True, True)
width=1
color='blue'
def change_color(event):
global color
if event.type =="2":
color = "red"
else:
color = "blue"
def drawing(event):
print(event)
if width>0: #양수라면
x1=event.x-1 #event 매개변수에는 자동으로 마우스 이벤트 객체가 전달된다
#event는 obj
#x는 속성
y1=event.y-1
x2=event.x+1
y2=event.y+1
canvas.create_oval(x1, y1, x2, y2, fill=color, width=width, outline=color, tags="paint")
def scroll(event):
print(event)
global width
if event.delta==120: #위로 굴릴 때
width+=1
if event.delta==-120: #아래로 굴릴 때
width-=1
label.config(text=str(width))
def invert_canvas():
items=canvas.find_withtag("paint")
for item in items:
current_fill=canvas.itemcget(item, 'fill')
if current_fill=='blue':
canvas.itemconfig(item,fill="red", outline="red")
elif current_fill=='red':
canvas.itemconfig(item,fill="blue", outline="blue")
canvas=tkinter.Canvas(window, relief="solid", bd=2)
canvas.pack(expand=True, fill="both")
canvas.bind("<B1-Motion>", drawing) #drawing 함수는 event 매개변수를 요청하지만 절달하지 않음
canvas.bind("<MouseWheel>", scroll) #scroll 함수도 event 매개변수에 값을 요청하지만 전달하는 값 없음
window.bind("<KeyPress-Up>", change_color)
window.bind("<KeyRelease-Up>", change_color)
btn_invert=tkinter.Button(window, text='반전', command=invert_canvas)
btn_invert.pack(side="left", padx=20)
label=tkinter.Label(window, text=str(width))
label.pack()
window.mainloop()

24강 Toplevel
Toplevel을 이용하여 다른 위젯들을 포함하는 외부 윈도우를 생성
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
menubar=tkinter.Menu(window)
menu_1=tkinter.Menu(menubar, tearoff=0)
menu_1.add_command(label="하위 메뉴 1-1")
menu_1.add_command(label="하위 메뉴 1-2")
menu_1.add_separator()
menu_1.add_command(label="하위 메뉴 1-3")
menubar.add_cascade(label="상위 메뉴 1", menu=menu_1)
toplevel=tkinter.Toplevel(window, menu=menubar)
toplevel.geometry("320x200+820+100")
label=tkinter.Label(toplevel, text="test")
label.pack()
window.mainloop()

import tkinter
def open_new_window():
toplevel=tkinter.Toplevel(window)
toplevel.title("서브 창")
toplevel.geometry("300x300")
label=tkinter.Label(toplevel,text='버튼으로 생성한 서브 창')
label.pack(pady=30)
btn_close=tkinter.Button(toplevel, text='닫기', command=toplevel.destroy)
btn_close.pack()
window = tkinter.Tk()
window.title("메인창 mainloop")
window.geometry("600x400")
btn_open=tkinter.Button(window, text="새 창 열기", command=open_new_window, width=10)
btn_open.pack()
window.mainloop()

헤드리스 추가(창 최소, 최대, 닫기 제거)
def open_new_window():
toplevel.overrideredirect(True) #헤드리스
25강 Spinbox
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
label=tkinter.Label(window, text="숫자를 입력하세요.", height=3)
label.pack()
def value_check(self):
label.config(text="숫자를 입력하세요.")
valid = False
if self.isdigit():
if int(self) > 50 or int(self) < 0:
return None
valid = True
elif self == '':
valid = True
return valid
def value_error(self):
label.config(text=str(self) + "를 입력하셨습니다.\n올바른 값을 입력하세요.")
validate_command=(window.register(value_check), '%P') #파이썬 함수를 tkinter 시스템이 이해할 수 있는 명령어로 변환
invalid_command=(window.register(value_error), '%P') #'%P' 수정된 후의 값 의미하는 예약어
spinbox=tkinter.Spinbox(window, from_ = 0, to = 50, validate = 'all', validatecommand = validate_command, invalidcommand=invalid_command)
spinbox.pack()
window.mainloop()

26강 ComboBox
import tkinter.ttk
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
values=[str(i)+"번" for i in range(1, 101)]
combobox=tkinter.ttk.Combobox(window, height=15, values=values)
combobox.pack()
combobox.set("목록 선택")
window.mainloop()

27강 Progressbar
Progressbar을 이용하여 현재 진행 상황을 표시
import tkinter.ttk
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
progressbar=tkinter.ttk.Progressbar(window, maximum=100, mode="indeterminate")
progressbar.pack()
progressbar.start(50)
window.mainloop()

28강 Notebook
import tkinter.ttk
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
notebook=tkinter.ttk.Notebook(window, width=300, height=300)
notebook.pack()
frame1=tkinter.Frame(window)
notebook.add(frame1, text="페이지1")
label1=tkinter.Label(frame1, text="페이지1의 내용")
label1.pack()
frame2=tkinter.Frame(window)
notebook.add(frame2, text="페이지2")
label2=tkinter.Label(frame2, text="페이지2의 내용")
label2.pack()
frame3=tkinter.Frame(window)
notebook.add(frame3, text="페이지4")
label3=tkinter.Label(frame3, text="페이지4의 내용")
label3.pack()
frame4=tkinter.Frame(window)
notebook.insert(2, frame4, text="페이지3")
label4=tkinter.Label(frame4, text="페이지3의 내용")
label4.pack()
window.mainloop()

29강 Sizegrip
import tkinter.ttk
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
def Drag(event):
x=sizegrip.winfo_x()+event.x
y=sizegrip.winfo_y()+event.y
sz_width=sizegrip.winfo_reqwidth()
sz_height=sizegrip.winfo_reqheight()
text["width"]=x-sz_width
text["height"]=y-sz_height
if x >= sz_width and y >= sz_height and x < window.winfo_width() and y < window.winfo_height():
text.place(x=0, y=0, width=x, height=y)
sizegrip.place(x=x-sz_width, y=y-sz_height)
text=tkinter.Text(window)
text.place(x=0, y=0)
sizegrip=tkinter.ttk.Sizegrip(window)
sizegrip.place(x=text.winfo_reqwidth()-sizegrip.winfo_reqwidth() , y=text.winfo_reqheight()-sizegrip.winfo_reqheight() )
sizegrip.bind("<B1-Motion>", Drag)
window.mainloop()

30강 TreeView
Treeview을 이용하여 행과 열로 구성된 표를 생성
import tkinter.ttk
#트리뷰는 표/테이블 표현하는 위젯 ttk에서 제공
window = tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(False, False)
def cc(self):
treeview.tag_configure("tag2", background="red")
treeview = tkinter.ttk.Treeview(window, columns=["one", "two"], displaycolumns=["two", "one"])
# 실제 데이터 순서와 상관없이 화면에는 two를 먼저 보여주고 그 뒤에 one을 보여주도록 순서 설정
treeview.pack()
treeview.column("#0", width=70)
treeview.heading("#0", text="num")
treeview.column("one", width=100, anchor="center")
treeview.heading("one", text="문자", anchor="e")
treeview.column("#2", width=100, anchor="w")
treeview.heading("two", text="ASCII", anchor="center")
treelist = [("A", 65), ("B", 66), ("C", 67), ("D", 68), ("E", 69)]
for i in range(len(treelist)):
treeview.insert('', 'end', text=i, values=treelist[i], iid=str(i) + "번")
top = treeview.insert('', 'end', text=str(len(treelist)), iid="5번", tags="tag1")
top_mid1 = treeview.insert(top, 'end', text="5-2", values=["SOH", 1], iid="5번-1")
top_mid2 = treeview.insert(top, 0, text="5-1", values=["NUL", 0], iid="5번-0", tags="tag2")
top_mid3 = treeview.insert(top, 'end', text="5-3", values=["STX", 2], iid="5번-2", tags="tag2")
treeview.tag_bind("tag1", sequence="<<TreeviewSelect>>", callback=cc)
# <<TreeviewSelect>> tag1 트리 항목이 선택되면 cc를 호출
window.mainloop()

31강 Separator
import tkinter.ttk
window = tkinter.Tk()
window.title("test")
window.geometry("640x480+100+100")
window.resizable(False, False)
button1 = tkinter.Button(window, width=10, height=5, text="1번")
button1.grid(row=0, column=0)
button2 = tkinter.Button(window, width=10, height=5, text="2번")
button2.grid(row=0, column=2)
button3 = tkinter.Button(window, width=10, height=5, text="3번")
button3.grid(row=1, column=1)
button4 = tkinter.Button(window, width=10, height=5, text="4번")
button4.grid(row=2, column=0)
button5 = tkinter.Button(window, width=10, height=5, text="5번")
button5.grid(row=2, column=2)
s = tkinter.ttk.Separator(window, orient="vertical")
s.grid(row=0, column=1, sticky='ns')
s2 = tkinter.ttk.Separator(window, orient="horizontal")
s2.grid(row=1, column=2, sticky='ew')
s3 = tkinter.ttk.Separator(window, orient="vertical")
s3.grid(row=1, column=0, sticky='ns')
window.mainloop()

32강 OpenCV 적용은 나중에
33강 람다 함수 적용
import tkinter
window=tkinter.Tk()
window.title("test")
window.geometry("640x400+100+100")
window.resizable(True, True)
def command_args(argument1, argument2, argument3):
global arg1
arg1 = argument1 * 2
print(argument1, argument2, argument3)
arg1 = 1
arg2 = "alpha"
arg3 = "beta"
button = tkinter.Button(window, width=25, height=10, text="버튼", command=lambda: command_args(arg1, arg2, arg3))
button.pack(expand=True, anchor="center")
window.mainloop()

실습
1.파일 불러오기 기능(csv, excel 파일 지원)
2.데이터에 대한 전처리 수행 기능
-이상치 확인, 제거 (대체)
-결측치 확인, 제거(대체)
3.테이블 구조 시각화 확인 가능
4.검색 기능
5.복사본 생성 기능
6.파생변수 생성 기능(np.where / assign 활용)(UI에서 활용)
7.원본/복사본/파생변수 생성본 중 선택해서 시각화 기능
8.데이터 수정 기능
9.요약 통계 조회 기능
10.데이터 타입 변환 및 정렬기능
11.변수 상관분석 및 히트맵 출력 기능(seaborn)
12.특정 조건 필터링 및 추출
13.전처리 내역 로그 기록 기능
14.최종 결과물 내보내기 export 기능)csv or xlsx)형태로
(기준점은 조원과 협의)
(UI와 df 활용하는 것이 목적)
주제: 온라인 쇼핑몰
'로보테크AI' 카테고리의 다른 글
| 융합_로보테크 AI 자율주행 로봇 개발자 과정-26/01/19 (0) | 2026.01.19 |
|---|---|
| 융합_로보테크 AI 자율주행 로봇 개발자 과정-26/01/15 (0) | 2026.01.15 |
| 융합_로보테크 AI 자율주행 로봇 개발자 과정-26/01/13[Tkinter] (1) | 2026.01.13 |
| 융합_로보테크 AI 자율주행 로봇 개발자 과정-26/01/12 (0) | 2026.01.12 |
| 융합_로보테크 AI 자율주행 로봇 개발자 과정-26/01/09[데이터 분석] (0) | 2026.01.09 |