대학교1학년 자바시간에 Awt, Swing 컴포넌트를 통해 GUI 프로그램을 만들 수 있다는 게 너무 신기했었는데
파이썬 GUI 프로그램을 보니 너무 신기하다

tkinter 라이브러리는 파이썬 설치시 자동으로 포함되어있으므로 따로 설치가 필요없다

 

■ Documentation
  https://docs.python.org/ko/3.9/library/tkinter.html#tkinter-modules

 

■ 기본 형태

from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로
#root.geometry("640x480+300+200")    # 가로x세로+x좌표+y좌표

root.resizable(False, False)    # x(너비), y(높이) 크기조정 비활성화(창 크기 변경안됨)

root.mainloop()

 

■ 버튼 

from tkinter import *

root = Tk()
root.title("겨울섬의 GUI")  # 타이틀 지정

btn1 = Button(root, text="버튼1") # 버튼 위젯 생성
btn1.pack() # 위젯 등록

btn2 = Button(root, padx=5, pady=10, text="버튼2")    # 버튼 내용에 따라 조정. 글자가 잘려보이지 않음. padx:좌우너비, pady:상하너비
btn2.pack()

btn3 = Button(root, padx=10, pady=5, text="버튼3")
btn3.pack()

btn4 = Button(root, width=10, height=3, text="버튼4") # 정해진 고정크기로 조정. 글자가 잘려보일 수 있음.
btn4.pack()

btn5 = Button(root, fg="red", bg="yellow", text="버튼5")  # fg:글자색, bg:배경색
btn5.pack()

# 이미지 버튼
photo = PhotoImage(file="이미지절대경로 포함 이미지명")
btn6 = Button(root, image=photo)
btn6.pack()

def btncmd():
    print("버튼이 클릭되었어요")

btn7 = Button(root, text="동작하는 버튼", command=btncmd) # 버튼에 동작 부여
btn7.pack()

root.mainloop()

 

■ 레이블

from tkinter import *

root = Tk()
root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")

label1 = Label(root, text="안녕하세요")
label1.pack()

# 이미지 레이블
photo = PhotoImage(file="이미지명")
label2 = Label(root, image=photo)
label2.pack()

def change():
    # 바꿀 레이블 문구
    label1.config(text="또 만나요")
    # 바꿀 이미지
    global photo2   # 전역변수로 선언해주어야 해당 함수호출이 완료된 후에도 유지
    photo2 = PhotoImage(file="이미지명")
    label2.config(image=photo2)

btn = Button(root, text="클릭", command=change)   # 버튼 클릭시 레이블 문구 변경
btn.pack()

root.mainloop()

 

■ 텍스트 & 엔트리
  - 텍스트 : 여러 줄을 입력받을 때 사용
  - 엔트리 : 한줄을 입력받을 때 사용

from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로

txt = Text(root, width=30, height=5)
txt.pack()
txt.insert(END, "글자를 입력하세요")    # 기본값

e = Entry(root, width=30)
e.pack()
e.insert(0, "한줄만 입력하세요")

def btncmd():
    # 텍스트와 엔트리 내용 가져오기
    print(txt.get("1.0", END))  # 라인1의 0번째 위치부터 끝까지 가져와라
    print(e.get())
    # 텍스트와 엔트리 내용 지우기
    txt.delete("1.0", END)
    e.delete(0, END)

btn = Button(root, text="클릭", command=btncmd)
btn.pack()

root.mainloop()

 

■ 리스트박스

from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로

'''
selectmode
  extended:여러개선택가능
  single:하나만선택가능
height
  0이면 리스트박스 내 리스트들을 모두 보여줌
  특정갯수 부여하면 그 특정갯수만큼만 바로 보여줌
'''
listbox = Listbox(root, selectmode="extended", height=0)
listbox.insert(0, "사과")
listbox.insert(1, "딸기")
listbox.insert(2, "바나나")
listbox.insert(END, "수박")
listbox.insert(END, "포도")
listbox.pack()

def btncmd():
    # 항목 삭제
    #listbox.delete(0) # END:맨 뒤 항목 삭제, 0:맨 앞 항목 삭제

    # 갯수 확인
    #print("리스트에는", listbox.size(), "개가 있습니다")

    # 항목 확인(시작,끝)
    #print("1번째부터 3번째까지의 항목 :", listbox.get(0,2))

    # 선택된 항목 확인(인덱스값으로 반환)
    print("선택된 항목 :", listbox.curselection())

btn = Button(root, text="클릭", command=btncmd)
btn.pack()

root.mainloop()

 

■ 체크 버튼

from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로

chkvar = IntVar()   # chkvar에 int형으로 상태값 저장
chkbox = Checkbutton(root, text="오늘 하루 보지 않기", variable=chkvar)
#chkbox.select() # 자동 선택
#chkbox.deselect()   # 자동 선택 해제
chkbox.pack()

chkvar2 = IntVar()
chkbox2 = Checkbutton(root, text="일주일동안 보지 않기", variable=chkvar2)
chkbox2.pack()

def btncmd():
    print(chkvar.get()) # 0:체크해제, 1:체크
    print(chkvar2.get())

btn = Button(root, text="클릭", command=btncmd)
btn.pack()

root.mainloop()

 

■ 라디오 버튼

from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로

Label(root, text="버거를 선택하세요").pack()

# 체크버튼과는 달리 라디오버튼은 하나의 변수값을 공유
burger_var = IntVar()   # int형으로 값 저장
btn_burger1 = Radiobutton(root, text="햄버거", value=1, variable=burger_var)
btn_burger1.select()    # 기본선택
btn_burger2 = Radiobutton(root, text="치즈버거", value=2, variable=burger_var)
btn_burger3 = Radiobutton(root, text="치킨버거", value=3, variable=burger_var)

btn_burger1.pack()
btn_burger2.pack()
btn_burger3.pack()


Label(root, text="음료를 선택하세요").pack()

drink_var = StringVar() # String형으로 값 저장
btn_drink1 = Radiobutton(root, text="콜라", value="콜라", variable=drink_var)
btn_drink1.select()
btn_drink2 = Radiobutton(root, text="사이다", value="사이다", variable=drink_var)

btn_drink1.pack()
btn_drink2.pack()


def btncmd():
    print(burger_var.get()) # 햄버거 중 선택된 라디오 항목의 값(value) 반환
    print(drink_var.get())

btn = Button(root, text="주문", command=btncmd)
btn.pack()

root.mainloop()

 

■ 콤보박스

import tkinter.ttk as ttk
from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로

values = [str(i) + "일" for i in range(1,32)]   # 1~31 까지의 숫자
combobox = ttk.Combobox(root, height=5, values=values)
combobox.pack()
combobox.set("카드 결제일")  # 최초 목록 제목 설정

readonly_combobox = ttk.Combobox(root, height=10, values=values, state="readonly")  # readonly:읽기전용
readonly_combobox.current(0)    # 0번째 인덱스 값 선택
readonly_combobox.pack()


def btncmd():
    print(combobox.get())   # 선택된 값 출력
    print(readonly_combobox.get())

btn = Button(root, text="선택", command=btncmd)
btn.pack()

root.mainloop()

 

■ 프로그래스 바

import time
import tkinter.ttk as ttk
from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로

'''
mode
  indeterminate : 결정되지않은것
  determinate : 결정된것
'''
'''
progressbar = ttk.Progressbar(root, maximum=100, mode="determinate")
progressbar.start(10)   # 10ms마다 움직임
progressbar.pack()

def btncmd():
    progressbar.stop()  # 작동 중지

btn = Button(root, text="중지", command=btncmd)
btn.pack()
'''

p_var2 = DoubleVar()    # Double형 값
progressbar2 = ttk.Progressbar(root, maximum=100, length=150, variable=p_var2)
progressbar2.pack()

def btncmd2():
    for i in range(1,101):  # 1~100
        time.sleep(0.01)    # 0.01초 딜레이

        p_var2.set(i)   # progressbar 값 설정
        progressbar2.update()   # UI 업데이트

        print(p_var2.get())

btn = Button(root, text="시작", command=btncmd2)
btn.pack()


root.mainloop()

 

■ 메뉴

from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로

def create_new_file():
    print("새 파일을 만듭니다.")

menu = Menu(root)

# File 메뉴
menu_file = Menu(menu, tearoff=0)
menu_file.add_command(label="New File", command=create_new_file)
menu_file.add_command(label="New Window")
menu_file.add_separator()   # 구분선
menu_file.add_command(label="Open File...")
menu_file.add_separator()
menu_file.add_command(label="Save All", state="disable")    # 비활성화
menu_file.add_separator()
menu_file.add_command(label="Exit", command=root.quit)
menu.add_cascade(label="File", menu=menu_file)

# Edit 메뉴
menu.add_cascade(label="Edit")

# Language 메뉴 추가(라디오버튼을 통해서 택1)
menu_lang = Menu(menu, tearoff=0)
menu_lang.add_radiobutton(label="Python")
menu_lang.add_radiobutton(label="Java")
menu_lang.add_radiobutton(label="C++")
menu.add_cascade(label="Language", menu=menu_lang)

# View 메뉴
menu_view = Menu(menu, tearoff=0)
menu_view.add_checkbutton(label="Show Minimap")
menu.add_cascade(label="View", menu=menu_view)

root.config(menu=menu)
root.mainloop()

 

■ 메시지 박스

import tkinter.messagebox as msgbox
from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로

# 기차 예매 예시
def info():
    msgbox.showinfo("알림", "정상적으로 예매 완료되었습니다.")  # 타이틀, 문구

def warn():
    msgbox.showwarning("경고", "해당 좌석은 매진되었습니다.")

def error():
    msgbox.showerror("에러", "결제 오류가 발생하였습니다.")

def okcancel():
    msgbox.askokcancel("확인/취소", "해당 좌석은 유아동반석입니다. 예매하시겠습니까?")

def retrycancel():
    response = msgbox.askretrycancel("재시도/취소", "일시적인 오류입니다. 다시 시도하시겠습니까?")
    if response == 1:
        print("재시도")
    elif response == 0:
        print("취소")

def yesno():
    msgbox.askyesno("예/아니오", "해당 좌석은 역방향입니다. 예매하시겠습니까?")

def yesnocancel():
    response = msgbox.askyesnocancel(title=None, message="예매 내역이 저장되지 않았습니다.\n저장 후 프로그램을 종료하시겠습니까?")
    # 네 : 저장 후 종료
    # 아니요 : 저장히자않고 종료
    # 취소 : 프로그램 종료 취소
    #print("응답 :", response) # True, False, None -> 예:1, 아니오:0, 그 외
    if response == 1:
        print("예")
    elif response == 0:
        print("아니오")
    else:
        print("취소")

Button(root, command=info, text="알림").pack()
Button(root, command=warn, text="경고").pack()
Button(root, command=error, text="에러").pack()

Button(root, command=okcancel, text="확인 취소").pack()
Button(root, command=retrycancel, text="재시도 취소").pack()
Button(root, command=yesno, text="예 아니오").pack()
Button(root, command=yesnocancel, text="예 아니오 취소").pack()

root.mainloop()

 

■ 프레임

from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로

Label(root, text="메뉴를 선택해주세요").pack(side="top")
Button(root, text="주문하기").pack(side="bottom")

# 버거 프레임
frame_burger = Frame(root, relief="solid", bd=1)  # relief:테두리 모양
frame_burger.pack(side="left", fill="both", expand=True)

Button(frame_burger, text="햄버거").pack()
Button(frame_burger, text="치즈버거").pack()
Button(frame_burger, text="치킨버거").pack()

# 음료 프레임
frame_drink = LabelFrame(root, text="음료")
frame_drink.pack(side="right", fill="both", expand=True)

Button(frame_drink, text="콜라").pack()
Button(frame_drink, text="사이다").pack()


root.mainloop()

 

■ 스크롤 바

from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로

frame = Frame(root)
frame.pack()

scrollbar = Scrollbar(frame)
scrollbar.pack(side="right", fill="y")

# set이 없으면 스크롤을 내려도 다시 올라옴
listbox = Listbox(frame, selectmode="extended", height=10, yscrollcommand=scrollbar.set)

for i in range(1,32):   # 1~31
    listbox.insert(END, str(i)+"일") # 1일, 2일, ...
listbox.pack(side="left")

# 스크롤바에도 리스트박스를 매핑해줘야함
scrollbar.config(command=listbox.yview)

root.mainloop()

 

■ 그리드

from tkinter import *

root = Tk()

root.title("겨울섬의 GUI")  # 타이틀 지정
root.geometry("640x480")   # 가로 x 세로

#btn1 = Button(root, text="버튼1")
#btn2 = Button(root, text="버튼2")
#btn1.pack()
#btn2.pack()
#btn1.pack(side="left")
#btn2.pack(side="left")
#btn1.grid(row=0, column=0)
#btn2.grid(row=1, column=1)

# 맨윗줄
btn_f16 = Button(root, text="F16", width=5, height=2)
btn_f17 = Button(root, text="F17", width=5, height=2)
btn_f18 = Button(root, text="F18", width=5, height=2)
btn_f19 = Button(root, text="F19", width=5, height=2)

btn_f16.grid(row=0, column=0, sticky=N+E+W+S, padx=3, pady=3)   # sticky:동서남북 지정한 방향으로 늘려줌.
btn_f17.grid(row=0, column=1, sticky=N+E+W+S, padx=3, pady=3)
btn_f18.grid(row=0, column=2, sticky=N+E+W+S, padx=3, pady=3)
btn_f19.grid(row=0, column=3, sticky=N+E+W+S, padx=3, pady=3)

# clear줄
btn_clear = Button(root, text="clear", width=5, height=2)
btn_equal = Button(root, text="=", width=5, height=2)
btn_div = Button(root, text="/", width=5, height=2)
btn_mul = Button(root, text="*", width=5, height=2)

btn_clear.grid(row=1, column=0, sticky=N+E+W+S, padx=3, pady=3)
btn_equal.grid(row=1, column=1, sticky=N+E+W+S, padx=3, pady=3)
btn_div.grid(row=1, column=2, sticky=N+E+W+S, padx=3, pady=3)
btn_mul.grid(row=1, column=3, sticky=N+E+W+S, padx=3, pady=3)

# 7 시작줄
btn_7 = Button(root, text="7", width=5, height=2)
btn_8 = Button(root, text="8", width=5, height=2)
btn_9 = Button(root, text="9", width=5, height=2)
btn_sub = Button(root, text="-", width=5, height=2)

btn_7.grid(row=2, column=0, sticky=N+E+W+S, padx=3, pady=3)
btn_8.grid(row=2, column=1, sticky=N+E+W+S, padx=3, pady=3)
btn_9.grid(row=2, column=2, sticky=N+E+W+S, padx=3, pady=3)
btn_sub.grid(row=2, column=3, sticky=N+E+W+S, padx=3, pady=3)

# 4 시작줄
btn_4 = Button(root, text="4", width=5, height=2)
btn_5 = Button(root, text="5", width=5, height=2)
btn_6 = Button(root, text="6", width=5, height=2)
btn_add = Button(root, text="+", width=5, height=2)

btn_4.grid(row=3, column=0, sticky=N+E+W+S, padx=3, pady=3)
btn_5.grid(row=3, column=1, sticky=N+E+W+S, padx=3, pady=3)
btn_6.grid(row=3, column=2, sticky=N+E+W+S, padx=3, pady=3)
btn_add.grid(row=3, column=3, sticky=N+E+W+S, padx=3, pady=3)

# 1 시작줄
btn_1 = Button(root, text="1", width=5, height=2)
btn_2 = Button(root, text="2", width=5, height=2)
btn_3 = Button(root, text="3", width=5, height=2)
btn_enter = Button(root, text="enter", width=5, height=2)

btn_1.grid(row=4, column=0, sticky=N+E+W+S, padx=3, pady=3)
btn_2.grid(row=4, column=1, sticky=N+E+W+S, padx=3, pady=3)
btn_3.grid(row=4, column=2, sticky=N+E+W+S, padx=3, pady=3)
btn_enter.grid(row=4, column=3, rowspan=2, sticky=N+E+W+S, padx=3, pady=3)  # rowspan:합칠 로우 갯수

# 0 시작줄
btn_0 = Button(root, text="0", width=5, height=2)
btn_point = Button(root, text=".", width=5, height=2)

btn_0.grid(row=5, column=0, columnspan=2, sticky=N+E+W+S, padx=3, pady=3)   # columnspan:합칠 컬럼 갯수
btn_point.grid(row=5, column=2, sticky=N+E+W+S, padx=3, pady=3)


root.mainloop()
Posted by 겨울섬
,