데이터 분석

0720

인뽕 2026. 7. 20. 21:34

 

 

GUI

 

파이썬 GUI가 필요한 이유

피지컬 AI(Physical AI)와 tkinter는 한마디로 인공지능이 탑재된 물리적 기기(로봇, 센서 등)를 조종하고 모니터링 하는 데스크톱 리모컨을 만드는 과정.

 

1. 두 기술의 역할 분담

이 둘을 결합할 때 각각은 명확한 역할을 수행합니다.

피지컬 AI (두뇌 + 감각/근육):
카메라, 마이크, 온습도 센서 등을 통해 현실 세계의 데이터를 수집.
이를 AI 모델(머신러닝 등)로 분석한 뒤
물리적인 행동(로봇 팔 이동, 모터 작동 등)을 수행하거나 데이터를 반환.

tkinter (사용자 소통 창구):
사람이 피지컬 AI의 상태를 눈으로 확인하고,
명령을 내릴 수 있도록
버튼, 그래프, 텍스트 입력창 등 GUI(그래픽 사용자 인터페이스)를 그려준다.

2. 대표적인 활용 사례

tkinter는 파이썬에 기본 내장되어 있어 별도 설치가 필요 없고 매우 가볍기 때문에,
피지컬 AI 연구나 하드웨어 제어 프로토타입을 만들 때 널리 쓰인다.

로봇 제어 패널 (HMI):
로봇의 현재 위치, 센서 값, 배터리 상태를 tkinter 창에 띄우고,
창에 있는 방향키 버튼을 눌러 로봇을 원격 조종한다.

엣지 디바이스(초소형 기기)의 터치스크린:
라즈베리파이(Raspberry Pi) 같은 소형 컴퓨터에 센서와 AI 모델을 올린 뒤,
작은 LCD 디스플레이에 tkinter로 만든 UI를 전체 화면으로 띄워
스마트 기기(음성 인식기, 스마트 도어록 등)처럼 작동하게 만든다.

실시간 AI 모니터링:
웹캠이 인식한 사람의 행동(비전 AI)이나
마이크로 들어온 음성 데이터 분석 결과를
tkinter 창에 텍스트나 그래프로 실시간 업데이트하여 보여준다.

3. 한계와 대안

피지컬 AI 시스템에 tkinter를 사용할 때 반드시 고려해야 할 가장 큰 한계는
'데스크톱 로컬 환경'에 묶인다는 점

 

- 출처 : https://cafe.naver.com/f-e/cafes/15757610/articles/15333?menuid=328&referrerAllArticles=false


 

tkinter

 

tkinter는 파이썬에서 GUI 프로그램을 만들 때 사용하는 표준 모듈이다.

GUI 창, 버튼, 라벨, 입력창 같은 요소들이 모두 이 모듈 안에 포함

 

#창 띄우기

import tkinter as tk

#tk,Tk() 는 GUI 프로그램의 기본 창
# 보통 루트 창(root Window)
root=tk.Tk()
root.title("tkinter로 파이썬 GUI 배우기")
root.geometry("200x500+100+300")# +연산자를 사용해서 창 시작 위치도 설정 가능"가로x세로+x좌표+y좌표"
root.configure(bg="white") # 창의 배경색 설정 bg는 백그라운드
#root.resizable(False, False)# 가로/세로 창 크기 변경 막아놓는 함수
#창 크기 변경 자체는 허용하되, 너무 작아지거나 너무 커지는 것을 막고 싶을 수 있습니다. 최소 창 크기와 최대 창 크기 지정 가능
#root.minsize(300, 200)
#root.maxsize(800, 600)

 

기본 윈도우를 띄우는 코드이다.

 

#라벨 (어디에, 어떤 글자를 표시하겠다)

 

label =tk.Label(root, text='라벨입니다.') #첫 인자로 root를 넣어 어떤 윈도우에 포함되는지 명시
label.pack()# root와 label을 패킹

label = tk.Label(
root,
text="Python GUI",
font=("맑은 고딕", 16),
fg="white",         #폰트 색
bg="navy"           #배경 색
)
label.pack(padx=40,pady=10)

라벨 함수의 여러 인자들.

 

#버튼

 

def hello():
    label.config(text="clicked button",fg="red")

button = tk.Button(root, text="click!", command=hello)
button.pack()

 

text 옵션은 버튼에 표시할 글자입니다.
command 옵션은 버튼을 클릭했을 때 실행할 함수를 지정합니다.
config() 는 이미 만들어진 위젯의 옵션을 변경할 때 사용합니다.
여기서는 라벨의 
text 옵션을 새 문자열로 바꾸었습니다
코드                              의미
command=hello       버튼을 클릭했을 때 hello 함수 실행
command=hello()     프로그램 시작 시 hello()를 바로 실행

 

#mainloop()

root.mainloop()
print("파이썬 핵심 요약 학습에 오신 것을 환영합니다!")

'''
mainloop()의 역할
# 콘솔 프로그램은 보통 위에서 아래로 실행된 뒤 종료.
하지만 GUI 프로그램은 조금 다르게 동작
# GUI 프로그램은 사용자가 어떤 행동을 할 떄까지 계속 기다린다.
#이러한 사용자의 동작을 이벤트라고 한다.
예) 창 닫기/ 버튼 클릭 / 키보드 입력/ 마우스 이동/ 창 크기 변경

tkinter 프로그램 세 단계
1. tkinter 모듈 가져오기
2. 기본 창 생성하기
3. mainloop()로 창 유지하기
-------------------------------------
'''

 

tkinter 프로그램 workflow

창 생성
⬇️
위젯 배치
⬇️
mainloop() 실행
⬇️
사용자 이벤트 대기
⬇️
이벤트 발생 시 처리
⬇️
창을 닫을 때까지 반복

 

#버튼 옵션과 상태적용 예제

 

import tkinter as tk
root = tk.Tk()
btn1 = tk.Button(root, text="두꺼운 테두리", bd=5, relief="raised", width=15)
# relief는 입체감이라는 뜻
# flat:평평함,sunken:화면 안으로 음푹 들어간 모양, groove: 테두리 선만 안으로 파인 모양, ridge: 테두리 선만 밖으로 튀어나온 모양,
# solid: 단순한 검은색 단선 테두리 사용 가능
btn1.pack(pady=5)
btn2 = tk.Button(root, text="커서 변경 (손가락)", cursor="hand2", bg="lightyellow")
#cursor에 쓸 수 있는 다른 유용한 옵션들
#"arrow" 기본 화살표 모양, "cross":십자선 모양(도면이나 그래프에서 위치를 지정할 때 유용
#"watch" : 시계 또는 모래시계 모양(로딩중이거나 작업중임을 나타낼 때 사용) "xterm": 텍스트 입력 칸에서 흔히 보이는 'I'모양의 텍스트 커서
btn2.pack(pady=5)
btn3 = tk.Button(root, text="클릭 불가", state="disabled")
btn3.pack(pady=5)
root.mainloop()

 

결과

#엔트리

'''
주요 옵션
옵션                      허용값                               설명

width   0 이상의 정수 (입력 문자 개수 기준)                  너비를 입력 문자 개수 기준으로 설정
font    ("맑은 고딕", 12) 형식의 튜플 또는 문자열             입력 글자의 글꼴, 크기, 스타일을 설정
fg      색상 이름( "black" ) 또는 16진수( "#000000" )       입력 글자의 색상을 설정
bg      색상 이름( "white" ) 또는 16진수( "#ffffff" )       입력 상자의 배경색을 설정
show    단일 문자 ( "*" 등)                                입력한 문자를 다른 문자로 표시(주로 비밀번호 입력창)
state   "normal" , "disabled" , "readonly"중 하나         입력 가능 상태를 설정
'''
# 비밀번호 입력 엔트리 만들기 예제
import tkinter as tk
root = tk.Tk()
password_entry = tk.Entry(root, show="*", width=30)
password_entry.pack(pady=20)
root.mainloop()

 

결과

 

 

# 텍스트 사용하기 예제

 

import tkinter as tk
root = tk.Tk()
text = tk.Text(root)
text.pack(pady=10)
root.mainloop()

결과

 

메모장 만들기가 이렇게 쉽다니... 윈플 실습 6-1은 지옥이었는데,,,

'''
메서드                         설명                          사용 예
get()               특정 범위의 텍스트 가져오기             text.get("1.0", tk.END)
delete()            특정 범위의 텍스트 지우기               text.delete("1.0", tk.END)
insert()            특정 위치에 텍스트 넣기                 text.insert("1.0", "안녕")


옵션                          허용값                                  설명
width                0 이상의 정수 (글자 수 기준)                     위젯의 너비를 '글자 수' 기준으로 설정
height               0 이상의 정수 (글자 수 기준)                     위젯의 높이를 '줄 수' 기준으로 설정
font                 ("Arial", 12) 형식의 튜플 또는 문자열            입력 글자의 글꼴, 크기 설정
bg                  색상 이름("white") 또는 16진수("#ffffff" )         배경색을 설정
fg                  색상 이름("white") 또는 16진수("#ffffff" )          글자색을 설정
wrap                "word" , "char" , "none" 중 하나                   텍스트가 위젯 너비를 넘어갈 때 줄바꿈 방식 설정

'''

 

 

#checkButton 예제

 

import tkinter as tk
def show_result():
    if agree_var.get():
        label.config(text="동의했습니다.")

root = tk.Tk()
agree_var = tk.BooleanVar()
check = tk.Checkbutton(root, text="동의합니다", variable=agree_var, command=show_result)
check.pack(padx=20, pady=20)
label = tk.Label(root, text="")
label.pack(pady=10)

root.mainloop()

 

결과

'''
주요 메서드
메서드                     설명
select()                체크 상태로 변경
deselect()              체크 해제 상태로 변경
toggle()                현재 상태를 반대로 변경
invoke()                사용자가 클릭한 것처럼 동작 실행

옵션                      허용 값                            설명                  
text                    임의의 문자열                     체크 버튼 옆에 표시할 문자열 설정
variable                Tkinter 변수 객체                체크 상태를 저장할 변수 설정  
onvalue                 정수 1 , 문자열 "yes" 등          체크되었을 때 변수에 저장할 값 설정
offvalue                정수 0 , 문자열 "no" 등           체크 해제되었을 때 변수에 저장할 값 설정
command                 함수 객체                        체크 상태가 바뀔 때 실행할 함수 설정
state                   "normal" , "disabled" 중 하나    위젯의 상태 설정

'''

 

#radiobutton 사용 예제

 

import tkinter as tk
root = tk.Tk()
food = tk.IntVar(value=1)
tk.Radiobutton(root, text="육고기", variable=food, value=1).pack()
tk.Radiobutton(root, text="해산물", variable=food, value=2).pack()
root.mainloop()

라디오버튼은 하나만 선택할 수 있는 체크박스이다.

결과

 

'''
주요 메서드
메서드                     설명
select()            라디오 버튼을 선택
deselect()          라디오 버튼의 선택 해제
invoke()            사용자가 클릭한 것처럼 동작 실행
주요 옵션
옵션                                  허용 값                                설명
text                                임의의 문자열                         라디오 버튼 옆에 표시할 문자열 설정
variable                            Tkinter 변수 객체                    선택값을 저장할 변수 설정
value                               변수 타입에 맞는 값                    라디오 버튼을 선택했을 때 변수에 저장할 값 설정
command                             함수 객체                            라디오 버튼을 선택했을 때 실행할 함수 설정
state                               "normal" , "disabled" 중 하나        위젯의 상태 설정

알아두기
Radiobutton은 같은 변수를 공유해야 합니다
여러 개의 Radiobutton이 하나의 그룹으로 동작하려면 모두 같은 variable을 사용해야 합니다.
'''

 

 

#리스트박스 예제

 

import tkinter as tk
def show_selected(event):
    label.config(text="선택한 항목: " + listbox.get(listbox.curselection()))
root = tk.Tk()
listbox = tk.Listbox(root, height=5)
listbox.pack(padx=10, pady=10)

for item in ["Python", "Java", "JavaScript", "C", "C++"]:
    listbox.insert(tk.END, item)
listbox.bind("<<ListboxSelect>>", show_selected)# 해당 항목에서 이벤트가 발생하면 특정 함수를 호출한다.
label = tk.Label(root, text="")
label.pack(pady=10)
root.mainloop()

 

결과

 

'''
메서드                     설명                                사용 예
insert()            항목 추가                        listbox.insert(tk.END, "Python")
delete()            항목 삭제                        listbox.delete(0)
get()               항목 가져오기                     listbox.get(0)
curselection()      선택된 항목의 인덱스 가져오기        listbox.curselection()
size()              전체 항목 개수 가져오기             listbox.size()
selection_set()     특정 항목 선택                    listbox.selection_set(0)
selection_clear()   선택 해제                       listbox.selection_clear(0, tk.END)

주요옵션
옵션                              허용 값                                        설명
width                0 이상의 정수 (글자 수 기준)                             위젯의 너비를 글자 수 기준으로 설정
height               0 이상의 정수 (줄 수 기준)                              표시할 항목의 줄 수 설정
selectmode          "browse" , "single" , "multiple" ,"extended" 중 하나   항목 선택 방식을 설정
font                ("Arial", 12) 형식의 튜플 또는 문자열                     목록 글자의 글꼴과 크기 설정
fg                  색상 이름( "black" ) 또는 16진수( "#000000" )            글자색 설정
bg                  색상 이름( "white" ) 또는 16진수( "#ffffff" )            배경색 설정

Listbox의 인덱스

Listbox의 항목 위치는 0부터 시작합니다. 첫 번째 항목은 0, 두 번째 항목은 1, 세 번째 항목은 2
입니다.
listbox.get(0)
위 코드는 Listbox의 첫 번째 항목을 가져옵니다.
'''

 

#스핀 박스 예제

 

import tkinter as tk
def show_value():
    label.config(text="선택한 수량: " + spinbox.get())
root = tk.Tk()
root.title("Spinbox 예제")
spinbox = tk.Spinbox(root, from_=1, to=10, width=10)
spinbox.pack(padx=10, pady=10)
button = tk.Button(root, text="확인", command=show_value)
button.pack(pady=5)
label = tk.Label(root, text="")
label.pack(pady=10)
root.mainloop()

스핀박스는 수량을 조절할 수 있는 박스이다.

결과

 

 

#문자열을 사용한 스핀박스

import tkinter as tk
def show_month():
    label.config(text="선택한 달: " + spinbox.get())
root = tk.Tk()
root.title("문자열 Spinbox")
#1월 부터 12월까지 선택할 수 있는 스핀박스
spinbox = tk.Spinbox(root, values=("1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"), width=10)
spinbox.pack(padx=10, pady=10)

#선택된 값을 확인하는 버튼
button = tk.Button(root, text="확인", command=show_month)
button.pack(pady=5)

label = tk.Label(root, text="")
label.pack(pady=10)
root.mainloop()

 

결과

'''
주요 메서드
메서드                     설명
get()               현재 값 가져오기
delete()            입력된 값 삭제
insert()            값 삽입

주요 옵션

옵션                              허용 값                                        설명
from_                       실수 또는 정수                                   시작값 설정
to                          실수 또는 정수                                   끝값 설정
increment                   0보다 큰 실수 또는 정수                           값이 증가하거나 감소하는 단위 설정
values                      문자열 튜플 또는 리스트                           선택할 문자열 목록 설정
width                       0 이상의 정수 (글자 수 기준)                      위젯의 너비 설정
command                     함수 객체                                       위아래 버튼을 눌러 값이 바뀔 때 실행할 함수 설정
state                       "normal" , "readonly" , "disabled"중 하나       입력 가능 상태 설정
�
�
 알아두기
Spinbox는 사용자가 값을 직접 입력할 수 있다는 점에서 Entry와 비슷합니다. 하지만
Spinbox는 정해진 범위나 목록 안에서 값을 선택하도록 만들 수 있다는 차이가 있습니다.
예를 들어 단순히 이름을 입력받을 때는 Entry가 적합하고, 수량이나 월처럼 제한된 값을 선
택할 때는 Spinbox가 적합합니다.

'''

 

 

# 스케일 사용 예제

 

import tkinter as tk
def show_value():
    label.config(text="선택한 볼륨: " + str(scale.get()))
root = tk.Tk()
scale = tk.Scale(root, from_=0, to=100, orient="horizontal")
scale.pack(padx=10, pady=10)
button = tk.Button(root, text="확인", command=show_value)
button.pack(pady=5)
label = tk.Label(root, text="")
label.pack(pady=10)
root.mainloop()

볼륨을 조절하는 스케일.

결과

 

# 밝기 세로 조절 예제

 

import tkinter as tk
def show_value():
    label.config(text=f"선택한 밝기: {scale.get()}")
root = tk.Tk()
scale = tk.Scale(root, from_=0, to=100, orient="vertical")
scale.pack(pady=10)
tk.Button(root, text="확인", command=show_value).pack()
label = tk.Label(root)
label.pack(pady=10)
root.mainloop()

결과

 

'''
주요 메서드                                              
메서드                                                  설명
get()                                            현재 Scale 값 가져오기
set()                                            Scale 값을 지정한 값으로 변경하기

주요 옵션

옵션                                      허용 값                                설명
from_                               실수 또는 정수                            시작값 설정
to                                  실수 또는 정수                            끝값 설정
orient                              "horizontal" , "vertical" 중 하나        Scale 방향 설정
length                              0 이상의 정수 (픽셀 단위)                  Scale의 길이 설정
resolution                          0보다 큰 실수 또는 정수                    값이 움직이는 간격 설정
tickinterval                        0 이상의 실수 또는 정수                    눈금 표시 간격 설정
label                               임의의 문자열                             Scale위젯에 표시할 제목 설정
command                             함수 객체                               값이 바뀔 때 실행할 함수 설정
state                               "normal" , "disabled" 중 하나          사용 가능 상태 설정

 알아두기
위젯마다 값을 가져오는 방식이 다릅니다
Checkbutton과 Radiobutton은 직접 위젯에서 값을 가져오기보다 연결된 변수에서 값을 가
져오는 방식이 일반적입니다.
반면 Listbox , Scale , Spinbox는 위젯의 get() 메서드를 사용하여 값을 가져올 수 있습
니다.
단, Listbox는 먼저 curselection()으로 선택된 항목의 위치를 확인한 뒤, 그 위치를 이용해
값을 가져와야 합니다.
'''

 

'''
관리자                         배치 방식                       어울리는 상황
pack()              한 방향으로 차곡차곡 쌓음                  단순한 세로/가로 나열
grid()              행·열 표 형태로 배치                        입력 폼, 설정 화면
place()             좌표로 직접 고정                           정밀한 고정 배치(특수한 경우)
'''

#pack() 레이아웃 예제

import tkinter as tk
root = tk.Tk()
root.geometry("200x150")
tk.Label(root, text="첫 번째 라벨 위젯", bg="red").pack()
tk.Label(root, text="두 번째 라벨 위젯", bg="green").pack()
tk.Label(root, text="세 번째 라벨 위젯", bg="yellow").pack()
root.mainloop()

결과

 

'''
주요 옵션
옵션                                  허용 값                                설명
side                    "top" , "bottom" , "left" , "right"             위젯을 붙일 방향
fill                    "x" , "y" , "both" , "none"                     남는 공간을 채우는 방향
expand                  True , False                                    남는 공간 차지 여부
anchor                  "n" , "s" , "e" , "w" , "ne" , "center" 등      할당된 공간 안에서의 정렬
padx / pady             정수 또는 (좌, 우) / (상, 하) 튜플                  위젯 바깥 여백
ipadx / ipady           정수                                             위젯 안쪽 여백

side가 "공간을 어디서 떼어올지"를 정한다면, anchor는 "그 공간 안에서 어느 쪽으로 정
렬할지"를 정합니다
'''

 

#side 예제

import tkinter as tk
root = tk.Tk()
root.geometry("400x300")
tk.Button(root, text="LEFT").pack(side="left")
tk.Button(root, text="RIGHT").pack(side="right")
root.mainloop()

 

결과

 

#fill과 expand 예제

 

import tkinter as tk
root = tk.Tk()
root.geometry("250x120")
tk.Button(root, text="가로만 채우기").pack(fill="x")
tk.Button(root, text="전체 확장").pack(expand=True, fill="both")
root.mainloop()
'''
위젯 숨기기
btn.pack_forget()
btn.pack()
'''

결과

 

#grid() 레이아웃

 

import tkinter as tk
root = tk.Tk()
root.geometry("180x50")
tk.Label(root, text="이름").grid(row=0, column=0)
tk.Entry(root).grid(row=0, column=1)
tk.Label(root, text="나이").grid(row=1, column=0)
tk.Entry(root).grid(row=1, column=1)
root.mainloop()

결과

 

'''
주요 옵션
옵션                      허용값                                         설명
row                     0 이상의 정수                                    위젯이 놓일 행 번호(0부터)
column                  0 이상의 정수                                    위젯이 놓일 열 번호(0부터)
columnspan              1 이상의 정수                                    위젯이 가로로 여러 칸 차지
rowspan                 1 이상의 정수                                    위젯이 세로로 여러 칸 차지
sticky                  "n" , "s" , "e" , "w" 및 조합("nsew" 등)        셀 안에서 위젯을 붙일 방향

'''

 

#span과 sticky 예제

 

import tkinter as tk
root = tk.Tk()
root.grid_columnconfigure(1, weight=1) #1번 열만 늘어남
opt = {"padx": 5, "pady": 5}
tk.Label(root, text="이메일 주소", bg="lightblue").grid(row=1, column=0, sticky="w", **opt)
tk.Entry(root, bg="lightyellow").grid(row=1, column=1, sticky="we", **opt)
tk.Button(root, text="로그인", bg="lightgreen").grid(row=2, columnspan=2, sticky="we", **opt)
root.mainloop()

결과

#선생님이 주신 예제

import tkinter as tk

root = tk.Tk()
root.geometry("250x150")

# 첫 번째 줄: 아주 긴 텍스트를 넣어 0번 열(Column)의 너비를 넓힘
lbl_long=tk.Label(root,text="이 라벨 때문에 격자의 너비가 넓어집니다.",bg="lightgray")
lbl_long.grid(row=0, column=0,pady=5)

# 두 번째 줄: 서쪽(왼쪽)에 달라붙는 버튼
btn_west = tk.Button(root,text="서쪽(w)에 붙음")
btn_west.grid(row=1, column=0, sticky="w", pady=5)

# 세 번째 줄: 동쪽(오른쪽)에 달라붙는 버튼
btn_east = tk.Button(root,text="동쪽에 붙음")
btn_east.grid(row=2, column=0, sticky="e", pady=5)

# 네 번째 줄: 가로로 꽉 채우는 버튼
btn_fill = tk.Button(root,text="가로로 꽉 채움(ew)")
btn_fill.grid(row=3, column=0, sticky="ew", pady=5)

root.mainloop()

결과

 

 

#행 열 늘리기

 

import tkinter as tk

root = tk.Tk()
root.title("반응형 창 만들기")
root.geometry("300x200")

#0번째 행과 0번째 열이 창 크기 변화에 반응하여 늘어나도록 가중치(weight) 부여
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

#텍스트 창 생성
text_widget = tk.Text(root,bg="lightyellow")

#넓어지는 격자(0행 0열) 안에서 동서남북(nsew)으로 꽉 채우도록 (sticky) 배치
text_widget.grid(row=0, column=0,sticky="nsew",padx=10,pady=10)

#하단 닫기 버튼(1번째 행에 배치. weight를 주지 않았으므로 크기 고정됨)
btn_close = tk.Button(root,text="닫기", command=root.quit)
btn_close.grid(row=1, column=0, pady=(0,10))

root.mainloop()

 

 

창의 크기를 바꿈에 따라 문자열의 줄바꿈도 바뀜

 

 

'''
메서드
grid_forget()
grid_remove()
위젯을 떼어내고 위치 정보도 잊음
설명
위젯을 떼어내되 위치 정보를 기억(다시 
grid() 호출 시 원래 자리로)
'''
#예제
import tkinter as tk
def toggle_widget():
    #winfo_ismapped()로 현재 화면에 보이는지 확인
    if text_box.winfo_ismapped():
        #숨길 때는 grid_remove() 사용 (위치 기억)
        text_box.grid_remove()
        btn_toggle.config(text="텍스트 창 보이기")
    else:
        #다시 나타낼 때는 아무 옵션 없이 grid()만 호출해도 원래 자리(row=1,column=0)로 돌아옴!
        text_box.grid()
        btn_toggle.config(text="텍스트 창 숨기기")

root =tk.Tk()
root.geometry("250x150")

btn_toggle = tk.Button(root,text= "텍스트 창 숨기기",command=toggle_widget)
btn_toggle.grid(row=0, column=0, pady=10, padx=10)


text_box=tk.Text(root,height=3,width=20,bg="lightyellow")
text_box.insert("1.0", "잠시 숨겨질 수 있는 \n수필 텍스트 입니다.")
#최초 배치 시 위치와 여백 설정 (이 설정을 grid_remove가 기억함)
text_box.grid(row=1, column=0, padx=20)

root.mainloop()

 

 

숨길수 있는 텍스트박스

 

 

#place() 레이아웃
#place() 는 위젯의 위치를 좌표로 직접 지정합니다.
#직관적이지만 창 크기 변화에 약하므로, 꼭 필요한 고정 배치에만 제한적으로 사용합니다.
#예제

import tkinter as tk
root = tk.Tk()
root.geometry("300x150")
tk.Label(root, text="절대 위치 (50, 30)", bg="lightblue").place(x=50, y=30) # 절대 좌표 배
tk.Label(root, text="상대 좌표 배치 (정중앙)", bg="lightgreen").place(
relx=0.5, rely=0.5, anchor="center") # 상대 좌표 배치 (relx, rely는 0.0 ~ 1.0 비율)

tk.Label(root, text="상대 크기 지정 (너비 80%)", bg="lightyellow").place(
relx=0.1, rely=0.8, relwidth=0.8
) # 상대 크기 지정 (relwidth, relheight)
root.mainloop()

 

창을 늘림에따라 위치가 바뀌는 상대좌표배치와, 바뀌지 않는 절대 위치

'''
주요 옵션
옵션                          허용 값                                설명
x , y                       정수(픽셀)                             절대 좌표(왼쪽 위 모서리 기준)
relx , rely                 0.0~1.0 실수                          부모 크기 대비 비율
anchor                      "n", "s", "e", "w", "ne", "center"등  기준점 위치
'''

 

#pack() 과 grid()

'''
레이아웃 관리자 혼용 규칙
같은 부모 위젯 안에서 
pack() 과 grid() 를 섞어 쓰면 안 됩니다.
두 관리자가 요구하는 창 크기가 충돌하면서 tkinter가 크기를 계속 재계산해, 창이 떨리거나 응답하지 않는 상태가 됩니다.
이때 명확한 예외(TclError )가 발생하지 않는 경우가 많아 원인을 찾기 어렵습니다.
'''

 

#Frame으로 계층 분리
#Frame 으로 구역을 나누면 됩니다.
#핵심은 "같은 부모 안에서만 한 가지 관리자를 쓴다" 는 것입니다. 부모가 다르면(창 vs. 프레임)
#서로 다른 관리자를 써도 괜찮습니다

 

#예제
import tkinter as tk
root = tk.Tk()
root.geometry("360x150")
root.configure(bg="#797777")
# 위쪽 프레임: 입력 폼 (내부는 grid)
top = tk.Frame(root, bg="#d7ecff", padx=5, pady=5)
top.pack(side="top", fill="x", padx=5, pady=5)
tk.Label(top, text="이메일 주소", bg="#d7ecff").grid(row=0, column=0, sticky="w", padx=10)
tk.Entry(top, bg="white").grid(row=0, column=1, sticky="we")
top.grid_columnconfigure(1, weight=1)  # 입력칸이 가로로 늘어나도록
# 아래쪽 프레임: 버튼 (내부는 pack)
bottom = tk.Frame(root, bg="#ffe0e0", padx=5, pady=5)
bottom.pack(side="bottom", fill="x", padx=5, pady=5)
tk.Button(bottom, text="확인", bg="#7bc96f", fg="white", width=8).pack(side="left")
tk.Button(bottom, text="취소", bg="#e87a7a", fg="white", width=8).pack(side="right")
root.mainloop()

 

결과

 

#이벤트 기반 프로그래밍 예제 한글은 2바이트 이므로 조금씩 늦음

import tkinter as tk
def on_key(event):
    result_label.config(text=f"입력된 키 : {event.char}")
root = tk.Tk()
entry = tk.Entry(root, width=30)
entry.pack(padx=20, pady=10)
result_label = tk.Label(root, text="입력된 키 : ", bg="lightyellow")
result_label.pack(padx=20, pady=10)
entry.bind("<Key>", on_key)
root.mainloop()

한글 '똥'은 2바이트라 실시간으로 반영되지 않는 모습

'''
분류                                       시퀀스                                     설명
마우스                                 <Button-1>                                      좌클릭
마우스                                 <Button-2>                                      휠 클릭
마우스                                 <Button-3>                                      우클릭
마우스                                 <ButtonRelease-1>                               버튼 뗌
마우스                                 <B1-Motion>                                     좌클릭 드래그
마우스                                 <Double-Button-1>                               더블클릭
마우스                                 <Enter> / <Leave>                               위젯 영역 진입 / 이탈
키보드                                 <KeyPress>                                      모든 키
키보드                                 <KeyPress-Return>                               엔터
키보드                                 <Key-Escape>                                    ESC
키보드                                 <Control-c>                                     Ctrl+C 조합
키보드                                 <a>                                             일반 문자키 (간단 표기)
윈도/포커스                              <Configure>                                    크기·위치 변경
윈도/포커스                              <FocusIn> / <FocusOut>                         포커스 획득 / 상실
윈도/포커스                              <Destroy>                                      위젯 소멸

'''

 

 

'''
메뉴
Menu는 프로그램 창 상단에 보이는 메뉴바입니다. 메모장에서 보이는 파일 / 편집 / 보기 같은
것들이 바로 Menu입니다.
큰 메뉴바 안에 작은 메뉴(파일, 편집 등)를 넣고, 그 안에 실제 항목(열기, 저장 등)을 넣는 계층
구조를 갖습니다.

메뉴 만드는 순서

메뉴바 역할을 할 Menu바를 생성합니다.
그 안에 넣을 하위 메뉴(Menu)를 생성합니다.
하위 메뉴는 add_command 등으로 항목을 채웁니다.
add_cascade로 하위 메뉴를 메뉴바에 연결합니다.
root.config(menu=...)로 메뉴바를 창에 부착합니다.
'''

 

#메뉴 사용 예제

import tkinter as tk
root = tk.Tk()
root.geometry("400x120")

menubar = tk.Menu(root)# 1) 메뉴바 생성

file_menu = tk.Menu(menubar, tearoff=0)# 2) 하위 메뉴 생성
file_menu.add_command(label="열기", command=lambda: print("열기 클릭")) # 3) 항목 채우기
file_menu.add_separator()
file_menu.add_command(label="종료", command=root.destroy)


menubar.add_cascade(label="파일", menu=file_menu)# 4) 메뉴바에 연결
root.config(menu=menubar)               # 5) 창에 부착
root.mainloop()

결과

 

'''
주요 메서드
메서드                                             설명
add_command(label, command)                        클릭하면 동작하는 일반 항목 추가
add_cascade(label, menu)                           하위 메뉴를 펼치는 항목 추가 (메뉴바에 메뉴 연결) 
add_separator()                                    항목 사이에 구분선 추가
add_checkbutton(label, variable)                   켜고 끌 수 있는 체크 항목 추가
add_radiobutton(label, variable, value)            여러 개 중 하나만 선택하는 항목 추가        
tk_popup(x, y)                                     지정한 화면 좌표에 메뉴를 팝업으로 표시
delete(index)                                      항목 삭제

주요 옵션                     
옵션                                허용 값                        설명
tearoff                 0 , 1 (또는 False /True )
label                   문자열
command                 함수(콜러블)                             항목 클릭 시 실행할 함수
accelerator             문자열(예:"Ctrl+S" )                     단축키 안내 문자열
state                   tk.NORMAL , tk.DISABLED ,tk.ACTIVE      항목 상태
underline               0 이상의 정수(글자 인덱스)                 항목 이름 중 한 글자에 밑줄을 그어 키보드 접근 문자로 지정
'''

 

 

import tkinter as tk
root = tk.Tk()
root.geometry("300x120")
menu = tk.Menu(root, tearoff=0)
menu.add_command(label="복사", command=lambda: print("복사"))
menu.add_command(label="붙여넣기", command=lambda: print("붙여넣기"))
label = tk.Label(root, text="이 글자 위에서 오른쪽 클릭", bg="lightyellow")
label.pack(pady=30)
label.bind("<Button-3>", lambda e: menu.tk_popup(e.x_root, e.y_root))
root.mainloop()

 

결과

 

'''
�
알아두기
팝업 좌표는 왜 x_root 일까?
tk_popup() 은 화면 전체를 기준으로 한 절대 좌표를 받습니다. 그래서 위젯 기준인 
e.y 가 아니라 e.x_root , e.y_root 를 넘겨야 클릭한 자리에 정확히 메뉴가 뜹니다.
'''

 

#대화상자

 

'''
Dialogs는 사용자와 잠깐 대화하기 위해 뜨는 팝업창입니다.
tkinter는 자주 쓰는 대화상자를 미리 만들어 제공하므로, 창을 직접 디자인하지 않고 함수 한 줄
로 호출할 수 있습니다.
대화상자는 크게 두 종류로 나뉩니다.

표준 대화상자

tkinter가 제공하는 
messagebox , filedialog , simpledialog 가 있습니다.
사용자 정의 대화상자
Toplevel 로 대화상자로 입력 필드가 여러 개거나 디자인을 짜야 할 때 직접 만드는 창입니다.

표준 대화상자

세 가지 주요 모듈
표준 대화상자는 용도에 따라 세 모듈로 나뉩니다.
모듈                               용도                            주요 메서드
messagebox                      알림, 경고, 예/아니오 질문        showinfo , askyesno            
filedialog                      파일/폴더 열기·저장 창           askopenfilename , asksaveasfilename           
simpledialog                    짧은 텍스트·숫자 입력받기          askstring , askinteger          

세 모듈 모두 tkinter 안에 있지만, 자동으로 따라오지 않으므로 별도로 import 해야 합니다.

from tkinter import messagebox, filedialog, simpledialog

대화상자는 "값을 반환한다"

표준 대화상자의 중요한 특징은 사용자의 선택·입력 결과를 반환값으로 돌려준다는 점입니다.
따라서 보통 결과 = 대화상자함수(...) 형태로 받아서 사용합니다.
모듈                              반환값                             취소했을 때
messagebox                      True / False                        보통 False
filedialog                      파일 경로 문자열                       빈 문자열 ""
simpledialog                    입력한 텍스트/숫자                      None

사용자가 취소하면 정상적인 값 대신 None이나 빈 문자열이 돌아옵니다. 반환값을 그대로 쓰기
전에 반드시 확인하는 습관이 필요합니다.
'''

 

#messagebox

#가장 자주 쓰는 모듈로 정보를 보여주거나 예/아니오를 묻습니다.

 

import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
def exit_app():
    if messagebox.askyesno("확인", "정말 종료할까요?"):
        root.destroy()
tk.Button(root, text="종료", command=exit_app).pack(padx=180, pady=48)
root.mainloop()

 

결과
종료를 누르면.

 

'''
messagebox 주요 메서드
메서드                                         설명
showinfo                                      정보 알림 표시 (확인 버튼)   
showwarning                                  경고 알림 표시 (확인 버튼)
showerror                                    오류 알림 표시 (확인 버튼)
askquestion                                  예/아니오 질문, "yes" /"no" 문자열 반환       
askyesno                                     예/아니오 질문, True /False 반환
askokcancel                                  확인/취소 질문, True /False 반환
askretrycancel                               재시도/취소 질문, True /False 반환
askyesnocancel                               예/아니오/취소 질문, True /False /None 반환

'''

 

 

#filedialog

#파일이나 폴더의 경로를 사용자에게 받아옵니다.

from tkinter import filedialog
path = filedialog.askopenfilename(
title="파일 선택",
filetypes=[("텍스트 파일", "*.txt"), ("모든 파일", "*.*")]
)
if path:
    print("선택한 파일:", path)

실행결과. 파일탐색기를 연다.

'''

filedialog 주요 메서드

메서드                                                 설명
askopenfilename                                     파일 하나 열기. 선택한 경로 문자열 반환 (취소 시 "" )
askopenfilenames                                    여러 파일 열기. 경로 튜플 반환 (취소 시 빈 튜플)
asksaveasfilename                                   저장할 경로 받기. 경로 문자열 반환 (취소 시 "" )                                   
askdirectory                                        폴더 선택. 폴더 경로 문자열 반환 (취소 시 "" )
askopenfile                                         파일을 열어 읽기용 파일 객체 반환 (취소 시 None )
asksaveasfile                                       파일을 열어 쓰기용 파일 객체 반환 (취소 시 None )

filedialog 주요 옵션

옵션                            허용                                       값설명
title                         문자열                                     대화상자 제목
initialdir                    폴더 경로 문자열                             처음 열릴 폴더 경로                   
filetypes                     (설명, 패턴) 튜플의 리스트 (예 : "*.txt"))]    표시할 파일 종류 제한    
defaultextension              확장자 문자열 (예: ".txt" )                  저장 시 자동으로 붙는 기본확장자
initialfile                   파일명 문자열                               저장 대화상자에 미리 채워질 파일명
'''

 

#simpledialog
#짧은 텍스트나 숫자를 입력받을 때 사용합니다.

from tkinter import simpledialog
name = simpledialog.askstring("입력", "이름을 입력하세요.")
age = simpledialog.askinteger("입력", "나이를 입력하세요.", minvalue=0, maxvalue=120)
if name:
    print(f"{name}님, {age}세")

결과

 

결과

 

'''
simpledialog 주요 메서드

메서드               설명
askstring         문자열 입력받기. 입력한 문자열 반환 (취소 시 None )
askinteger        정수 입력받기. minvalue , minvalue , maxvalue 로 범위 제한 가능 (취소 시 None )
askfloat          실수 입력받기. maxvalue 로 범위 제한 가능 (취소 시 None )

'''

 

#사용자 정의 대화상자

'''
messagebox 나 filedialog 는 정해진 모양만 제공합니다.
입력 필드가 여러 개 필요하거나 디자인을 직접 짜고 싶다면 새 창을 직접 만들어야 하며, 이때
사용하는 것이 Toplevel 위젯입니다.

Toplevel이란?

Tk() 가 프로그램의 메인 창이라면, 메인 창처럼 Toplevel() 은 그 위에 추가로 띄우는 새 창입니다.
Label , Entry , Button 등 모든 위젯을 넣을 수 있습니다.
메인 창에 종속된 자식 창이므로, 메인 창을 닫으면 함께 닫힙니다.
비 모달 방식 대화상자
메인 창과 동시에 떠 있으며 둘 다 자유롭게 조작할 수 있는 방식을 비 모달(modeless) 이라고 합
니다.
'''

 

import tkinter as tk
root = tk.Tk()
root.title("메인 창")
root.geometry("300x200")
def open_window():
    win = tk.Toplevel(root) # 새 창 생성
    win.title("새 창")
    tk.Label(win, text="이건 새 창입니다!").pack(pady=20)
    tk.Button(win, text="닫기", command=win.destroy).pack()
tk.Button(root, text="새 창 열기", command=open_window).pack(pady=50)
root.mainloop()

 

 

 

 

#모달(Modal) 대화상자

'''
사용자가 입력을 끝낼 때까지 메인 창을 막아두는 방식을 모달(Modal) 창이라 합니다.
설정 변경이나 필수 입력처럼 반드시 응답을 받아야 할 때 사용합니다.
모달은 다음 세 가지 설정으로 만듭니다.

메서드                                     설명
transient(root)                         메인 창에 종속시킴 (항상 위에 표시)
grab_set()                              모든 입력을 이 창에만 집중
wait_window(dialog)                     이 창이 닫힐 때까지 코드 실행을 멈추고 대기
'''
'''
사용자가 입력을 끝낼 때까지 메인 창을 막아두는 방식을 모달(Modal) 창이라 합니다.
설정 변경이나 필수 입력처럼 반드시 응답을 받아야 할 때 사용합니다.
모달은 다음 세 가지 설정으로 만듭니다.

메서드                                     설명
transient(root)                         메인 창에 종속시킴 (항상 위에 표시)
grab_set()                              모든 입력을 이 창에만 집중
wait_window(dialog)                     이 창이 닫힐 때까지 코드 실행을 멈추고 대기
'''

이름 입력을 완료할때까지 메인 창은 꺼지지 않는다.

#캔버스

'''
도형 그리기 (Shapes)

선, 사각형, 원 그리기

Canvas는 다양한 도형을 그리는 create_ 로 시작하는 메서드를 제공합니다.
각 도형은 고유한 ID(정수)를 반환하며, 이를 통해 나중에 도형을 수정할 수 있습니다.
원(Oval)은 해당 원을 둘러싸는 가상의 직사각형(Bounding Box)의 좌측 상단 좌표와 우측 하단
좌표를 입력하여 그립니다.
'''

 

#선, 사각형, 점선 원 그리기
#캔버스에 직선과 사각형, 점선 테두리의 타원을 각각 색을 달리하여 출력합니다.

import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=250, bg="#F8F3C0", highlightthickness=0)
canvas.pack()
canvas.create_line(50, 50, 350, 50, fill="#6194FA", width=7)
canvas.create_rectangle(50, 90, 150, 190, fill="#F58C9F", width=1)
canvas.create_oval(200, 90, 300, 190, fill="#88EBD4", width=1, dash=(5, 2))
root.mainloop()

 

결과

 

'''
주요 메서드
메서드                                                 설명
create_line(x1, y1, x2, y2, ...)                    직선 그리기
create_rectangle(x1, y1, x2, y2, ...)               직사각형 그리기
create_oval(x1, y1, x2, y2, ...)                    타원이나 원 그리기
create_polygon(x1, y1, x2, y2, x3, y3, ...)         3개 이상의 점을 연결한 다각형 그리기

주요 옵션
옵션                              허용                              값설명
fill            색상 이름( "red" ) 또는 16진수 값( "#ff0000" )       도형 내부를 채울 색상
outline         색상 이름( "black" ) 또는 16진수 값( "#000000" )     도형의 테두리 색상
width           정수 또는 실수 (픽셀 단위, 예: 2 , 1.5 )              선이나 테두리의 두께
dash            정수 튜플(예: (5, 3) ) 또는 문자열(예:"." , "-" )     점선 스타일 지정 (예 : (5, 3)은 5픽셀 긋고3픽셀 띄움)
'''

 

 

#캔버스에 그리기 예제

 

import tkinter as tk

old_x,old_y =None,None

def start_draw(event):
    global old_x,old_y
    old_x,old_y = event.x, event.y
def draw_line(event):
    global old_x,old_y
    if old_x and old_y:
        canvas.create_line(old_x, old_y, event.x, event.y, width=2,fill="black")
        old_x,old_y = event.x, event.y
root = tk.Tk()

canvas=tk.Canvas(root,width=400,height=300,bg="white",cursor="crosshair")
canvas.pack()

canvas.bind("<Button-1>", start_draw)
canvas.bind("<B1-Motion>", draw_line)

root.mainloop()

결과

'''
텍스트 및 이미지 삽입

캔버스에 텍스트와 사진 출력하기

Canvas 상의 특정 좌표를 지정하여 문자열을 렌더링할 수 있습니다.
PhotoImage 객체를 활용하여 이미지를 삽입할 수 있습니다.
이미지는 가비지 컬렉터(Garbage Collector)에 의해 삭제되지 않도록 전역 변수로 관리하거나 객
체에 참조를 남겨야 합니다.

문구와 이미지 출력하기

캔버스 중앙에 텍스트를 표시하고, 이미지 파일이 있으면 출력하며 없으면 안내 문구로 대체합니다.
코드가 저장된 동일한 경로에 200x200 크기의 'image.png' 파일을 위치해 둡니다.
'''

 

import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=300, bg="white")
canvas.pack()
canvas.create_text(200, 50, text="Canvas 입니다.", font=("Arial", 15, "bold"), fill="purple")
try:
    img = tk.PhotoImage(file="image.png")
    canvas.image = img
    canvas.create_image(200, 180, image=img, anchor="center")
except tk.TclError:
    canvas.create_text(200, 180, text="(이미지가 없습니다.)")
root.mainloop()

고양이그림으로 저장햇는데 잘렸네..

 

'''
객체 제어 및 애니메이션

도형 이동 및 속성 변경하기

Canvas에 그려진 모든 항목은 고유 식별자(ID) 또는 사용자가 지정한 문자열 태그(Tag)로 제어할
수 있습니다.
move() 메서드와 after() 메서드를 결합하면 간단한 애니메이션 효과를 구현할 수 있습니다.
'''

#버튼 클릭으로 원을 오른쪽으로 이동시키기
#버튼을 누르면 파란 원이 50ms 간격으로 오른쪽으로 움직이다가 화면 끝에 닿으면 멈춥니다.

 

import tkinter as tk
def move_circle():
    canvas.move("my_circle", 5, 0)
    coords = canvas.coords("my_circle")
    if coords[2] < 400:
        root.after(50, move_circle)
root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=200, bg="white")
canvas.pack()

canvas.create_oval(10, 80, 50, 120, fill="blue", tags="my_circle")

btn = tk.Button(root, text="이동 시작", command=move_circle)
btn.pack(pady=10)

root.mainloop()

 

 

이동 시작을 누르면 캔버스 끝까지 이동함.

'''
주요 메서드
메서드                                             설명
move(id_or_tag, dx, dy)                         객체를 현재 위치에서 dx, dy만큼 이동
coords(id_or_tag, [x1,y1...])                   객체의 현재 좌표를 반환하거나 새로운 좌표로 재설정
itemconfig(id_or_tag,options)                   생성된 객체의 옵션(색상, 두께 등)을 동적으로 변경
delete(id_or_tag)                               객체를 캔버스에서 삭제합. 모두 지우려면 canvas.delete("all") 을 사용

주요 옵션
옵션                      허용 값                                    설명
tags        문자열 또는 문자열 튜플(예 : ("tag1", "tag2"))             도형에 하나 이상의 태그를 부여하여, 동일 태그가 지정된 여러 도형을 그룹으로 묶어 한 번에 조작(이동, 색상 변경, 삭제 등)할 수 있게 함
'''

#ttk 위젯과 스타일링

'''
ttk 소개와 기본 개념
tkinter 위젯과 ttk 위젯의 차이
외관이 OS 테마(Windows, macOS, Linux)에 자연스럽게 어울립니다.
색상·폰트 등을 위젯 옵션이 아닌 Style 객체로 관리합니다. 그래서 bg=, fg= 같은 옵션이 ttk 위젯
에는 없거나 무시되는 경우가 많습니다.
ttk는 Tk 8.5부터 도입되었습니다. Tk 버전은 다음과 같이 확인할 수 있습니다.
import tkinter
print("Tk Version:", tkinter.TkVersion)
print("Tcl Version:", tkinter.TclVersion)
'''

 

#ttk 기본 예제(Label, Entry, Button)

 

import tkinter as tk
from tkinter import ttk
root = tk.Tk()
label = ttk.Label(root, text="이름 : ")
label.grid(row=0, column=0, padx=5, pady=5)
entry = ttk.Entry(root)
entry.grid(row=0, column=1, padx=5, pady=5)
button = ttk.Button(root, text="확인", command=lambda: print(entry.get()))
button.grid(row=1, column=0, columnspan=2, pady=5)
root.mainloop()

 

결과

'''
스타일링과 테마

Style을 이용한 외관 제어

ttk의 핵심은 ttk.Style 객체입니다.위젯 클래스마다 스타일 이름(예 :TLabel )이 정해져 있으며, 
이를 통해 외관을 일괄 변경할 수 있습니다.
일반 tkinter 위젯은 위젯마다 font , bg 등의 옵션을 직접 지정하지만, ttk는 스타일을 한 번 
정의해두면 같은 스타일을 쓰는 모든 위젯에 일괄 적용됩니다.
'''

 

import tkinter as tk
from tkinter import ttk

root = tk.Tk()

style = ttk.Style()#스타일을 제어하는 객체를 생성
style.configure("TButton", font=("맑은 고딕", 11), padding=6)#기본 버튼 스타일인 TButton 을 수정
style.configure("Accent.TButton", foreground="lightgreen", background="green")#Accent.TButton이라는 사용자 정의 스타일 생성

btn1 = ttk.Button(root, text="기본 버튼")#기본 스타일 적용
btn1.pack(padx=50, pady=5)

btn2 = ttk.Button(root, text="강조 버튼", style="Accent.TButton")#사용자 정의 스타일을 적용
btn2.pack(padx=50, pady=5)

root.mainloop()

 

ttk를 사용하면 이렇게 이쁜 버튼을 만들 수 있다.

 

#테마 선택
#ttk는 테마를 제공하며 다음 코드로 사용 가능한 테마와 현재 사용중인 테마를 확인할 수 있습니다.

 

import tkinter as tk
from tkinter import ttk
root = tk.Tk()
style = ttk.Style()
print(style.theme_names())
print(style.theme_use())
root.mainloop()

결과:현재 테마의 모습

#테마를 변경하는 코드

 

import tkinter as tk
from tkinter import ttk
root = tk.Tk()
style = ttk.Style()
frm = ttk.Frame(root, padding=20)
frm.pack()
cur = tk.StringVar(value=style.theme_use()) #콤보박스에 연결할 문자열 변수 정의
cb = ttk.Combobox(frm, values=style.theme_names(), textvariable=cur, state="readonly")#선택 가능한 테마 목록을 콤보박스로
cb.pack(pady=5)
cb.bind("<<ComboboxSelected>>", lambda e: style.theme_use(cur.get()))#항목 선택 시 이벤트에 함수를 연결
ttk.Button(frm, text="버튼").pack(pady=5)
ttk.Checkbutton(frm, text="체크박스").pack(pady=5)
ttk.Progressbar(frm, value=60).pack(pady=5)
root.mainloop()

테마형식을 선택할 수 있다.
classic테마의 버튼, 체크박스, 프로그레스 바

#상태(state)와 동적 스타일
#ttk 위젯은 active , pressed , disabled , focus 등의 상태를 가지며, style.map() 으로 상태별 외관을 지정할 수 있습니다.

 

import tkinter as tk
from tkinter import ttk
root = tk.Tk()
style = ttk.Style()
style.theme_use("clam")
style.map("TButton",
background=[("active", "lightblue"),
("pressed", "blue"),
("disabled", "lightyellow")],
foreground=[("disabled", "gray")])
ttk.Button(root, text="마우스를 올려보세요").pack(padx=20, pady=10)
root.mainloop()

결과

#콤보박스

'''
사용자가 드롭다운 목록에서 항목을 고르거나, 직접 값을 입력할 수 있습니다.
항목이 선택되면 <<ComboboxSelected>> 가상 이벤트가 발생합니다.

콤보박스 사용하기

리스트로 넘겨받은 도시 이름을 콤보박스에서 사용해 선택된 값을 출력합니다.
'''

 

import tkinter as tk
from tkinter import ttk
root = tk.Tk()
combo = ttk.Combobox(root, values=["서울", "부산", "대구"])
combo.set("서울")
combo.bind("<<ComboboxSelected>>", lambda e: print(combo.get()))
combo.pack(padx=20, pady=20)
root.mainloop()

 

결과

 

'''
주요 메서드
메서드                                             설명
get()                                           현재 입력되거나 선택된 값을 반환
set(value)                                      콤보박스의 값을 지정한 값으로 설정
current(index)                              인자가 없으면 선택된 항목의 인덱스를 반환하고, 인덱스를 주면 해당 항목을 선택
insert(index,value)                         입력 영역의 지정 위치에 문자열을 삽입
delete(first, last)                         입력 영역에서 지정 범위의 문자를 삭제
configure(options)                          위젯의 옵션을 동적으로 변경 (config 도 동일)
bind(event, func)                           특정 이벤트에 콜백 함수를 연결

주요 옵션
옵션                                       허용                                     값설명
values                        리스트 또는 튜플 (예: ['A', 'B','C'] )                드롭다운 목록에 표시할 항목
state                           normal , readonly , disabled                     입력 상태를 지정
textvariable                StringVar 등의 변수 객체                              값과 연동할 StringVar 등의 변수를 지정
width                       정수 (문자 단위)                                      위젯의 너비(문자 단위)를 지정
height                      정수 (항목 수)                                       드롭다운 목록에 한 번에 표시할 항목 수를지정
justify                  left , center , right                                  입력 텍스트의 정렬 방식을 지정
font                    폰트 지정 (예: ('맑은 고딕', 12) )                         표시 글꼴을 지정
postcommand             함수 또는 콜백 객체                                         드롭다운 목록이 열리기 직전에 호출할 함수를 지정

'''

 

 

'''
프로그레스바
작업의 진행 상황을 막대 형태로 시각화하는 위젯입니다.
진행률을 알 수 있을 때는 determinate 모드로 값을 채우고, 알 수 없을 때는 indeterminate
모드로 막대를 움직여 작업 중임을 표시합니다.
파일 다운로드, 설치, 데이터 처리 등 시간이 걸리는 작업의 상태를 사용자에게 알려줄 때 주로
사용합니다.
프로그레스바 사용하기
버튼을 클릭하면 Progressbar가 10%씩 증가합니다.
'''
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
pb = ttk.Progressbar(root, length=200, mode="determinate", maximum=100)
pb.pack(padx=20, pady=20)
pb["value"] = 0
def step():
    pb["value"] = (pb["value"] + 10) % 110

ttk.Button(root, text="+10", command=step).pack(pady=5)
root.mainloop()

+10 버튼으로 프로그레스 바 조절 가능

 

'''
주요 메서드
메서드                                         설명
start(interval=50)                      indeterminate 모드에서 애니메이션을 시작.interval 은 갱신 간격(ms) 
stop()                                  애니메이션 중지
step(amount=1.0)                        현재 값을 amount 만큼 증가 maximum 을 넘으면 0으로 순환
주요 옵션

옵션                                  허용 값                                    설명 
mode                            determinate , indeterminate                 값 기반 또는 애니메이션 모드를 지정
maximum                         실수 (기본값 100 )                           진행률의 최대값
value                           실수 (0 ~ maximum)                          현재 진행 값. determinate 모드에서 사용
variable                        IntVar 또는 DoubleVar 변수 객체               진행 값을 담을 변수를 연결 
length                          정수 (픽셀)                                  진행바의 길이
orient                          horizontal , vertical                       방향을 지정함

'''

 

'''
노트북 (탭)

여러 페이지를 탭으로 묶어, 클릭으로 전환할 수 있게 해주는 위젯입니다.
각 탭에는 보통 Frame을 연결하고, 그 안에 원하는 위젯을 배치합니다.
노트북 으로 탭 기능 사용하기
두 개의 프레임을 '메인 탭', '설정 탭'으로 구성합니다.
'''

 

결과. 메인,설정탭이 있다.

'''
주요 메서드
메서드                                                     설명
add(child, [options])                           새 탭을 추가. text로 탭 이름을 지정
insert(index, child, [options])                 지정한 위치( index )에 탭을 삽입
forget(tab_id)                                  해당 탭을 제거
select(tab_id)                                  지정한 탭을 선택(전환). 인자가 없으면 현재 선택된 탭을 반환
index(tab_id)                                   탭의 인덱스를 반환. "end"를 넘기면 탭 개수를 반환
tab(tab_id, **options)                          특정 탭의 옵션을 조회하거나 변경
주요 옵션
옵션                              허용                            값설명
text                            문자열                         탭에 표시할 이름 ( add / insert에서 사용)
state                    normal , disabled , hidden             탭 상태를 지정
image                    PhotoImage 등 이미지 객체                탭에 표시할 이미지
compound                 left , right , top , bottom ,center    텍스트와 이미지를 함께 배치할 때 위치를 지정
padding                  정수 또는 (좌, 상, 우, 하) 형식            탭 내부 여백
sticky                   n , s , e , w의 조합                   연결된 자식 위젯이 탭 영역에서 정렬·확장되는방식을 지정

'''

 

#트리뷰

'''
데이터를 행과 열로 표시하는 위젯으로, 표와 트리를 표현할 수 있습니다.
각 행은 항목(item)이며, 부모-자식 관계로 펼치고 접을 수 있는 트리 구조를 만들 수 있습니다.
'''

#트리뷰 사용하기

import tkinter as tk
from tkinter import ttk
root = tk.Tk()
tree = ttk.Treeview(root, columns=("item", "spec", "price"), show="headings")
tree.heading("item", text="제품")
tree.heading("spec", text="스펙")
tree.heading("price", text="가격")
data = [("가방", "16인치", 123), ("청소기", "700W", 250), ("운동화", "275mm", 54)]
for item, spec, price in data:
    tree.insert("", "end", values=(item, spec, price))

tree.pack(padx=5, pady=5, expand=True, fill="both")
root.mainloop()

결과

'''
메서드                                             설명
insert(parent, index,**options)             항목을 추가. parent 가 "" 이면 최상위 항목. 추가된 항목 ID를 반환
delete(*items)                              지정한 항목을 삭제
heading(column, **options)                  열 머리글의 텍스트나 정렬 명령 등을 설정
column(column, **options)                   열의 너비, 정렬 방식 등을 설정
item(item, **options)                       특정 항목의 값이나 옵션을 조회·변경
selection()                                 현재 선택된 항목들의 ID를 반환
set(item, column, value)                    특정 항목의 셀 값을 조회하거나 변경
get_children(item="")                       해당 항목의 자식 항목 ID 목록을 반환

주요 옵션
옵션                                   허용 값                               설명
columns                             식별자 목록                          표시할 열들의 식별자 목록
show                                tree , headings , 또는 둘 다를조합     표시 영역을 지정
selectmode                          browse ,extended (기본), none         선택 방식(단일/다중/비활성)          
height                              정수                                  한 번에 보이는 행의 개수
text                                문자열                                 항목의 트리 열에 표시할 텍스트 (사용)                               
values                              값 목록                            항목의 각 열에 들어갈 값들 (insert 에서 사용)                              
anchor                              center ,w , e등                      열 내 텍스트 정렬 위치 (column 에서 사용)                    
'''

'데이터 분석' 카테고리의 다른 글

0722 MVP, 스레드  (1) 2026.07.22
0721 아키텍처/데이터파이프라인 +GUI  (0) 2026.07.21