python(0821-0908)/활용2. GUI(0903-0906)

2.GUI : tkinter 익히기

나도초딩 2022. 9. 3.

간단한 프로그램 만드는 사람들 참 부러웠는데, 어찌됐건 이제야 해본다.

생각해보니, 웹이 어려운거였다. 신경쓸게 참 많았으니까.

 

따라해보는데, 왜 이리도 진도가 안나가고 흥미가 안느껴질까.... 하....

어려워서가 그런게 아니라, 기초가 지루하니까, 겨우 30분 1시간 기초과정을 익힐 때 ...왜 그럴까나.

기초라서 이해면에서 쉽다고 생각해서, 멍때리고 보니까 고질병인것 같다.

 

영상강의와 교재를 통한 강의의 가장 큰 차이가 이 부분인 듯 하다. 먼저 개괄적으로 본 다음 무엇을 배우는지, 어떤 문법 특징을 말하려는지 한번 살피고, 들어가면 더 좋을 듯 한데.

 

1. 기본세팅(create_frame)

root = Tk()
root.title("나도코딩")
root.geometry("640x480+900+100")

############################

root.mainloop()

2. Button() 과 PhotoImage()

버튼 안에, text 또는 이미지 !

btn1 = Button(root, text="버튼")

btn1 = Button(root, text="동작하는 버튼", command=btncmd)

 

# PhotoImage 는 버튼이나 label 에 사용

photo = PhotoImage(file="")

btn2 = Button(root, image=photo)

btn2.pack()

label2 = Label(root, image=photo)

label2.pack()

3. Label() : 버튼클릭(함수지정) 

버튼클릭->label과 image 변경 (--> config() 메서드로 속성 변경)
함수 내에서 photo2 선언시, 전역변수(global)로 안하면, garbage collector 가 지워버림.

photo = PhotoImage(file = "2_gui/img.png")
label2 = Label(root, image = photo)

def change():
    label1.config(text="또 만나요")
   

global photo2
    photo2 = PhotoImage(file="")
    label2.config(image=photo2)

 

4. Text 와 Entry : insert, delete, get()

# Text() 와 Entry() 는 유사. 
# Entry() 는 1 줄이여서, row 옵션이 없다는 것.

txt = Text(root, width=30, height=5)
txt.pack()

e = Engry(root, width=30)
e.pack()
txt.insert("1.0", "첫 줄 입력")
e.insert(END, "첫 줄 입력") # entry 는 한 줄이여서, END 대신 0 을 써도 동일
txt.insert(END, "글자를 입력하세요")
e.insert(END, "한 줄만 입력하세요") # 0 대신 END 써도 동일

# delete (범위),(insert 는 위치였지만, 삭제는 범위)
txt.delete("1.0", END) # 전부 삭제
e.delete(0, END) 

print(txt.get("1.0", END)) # 1: 첫째 줄, 2:0번째 컬럼
# entry 에서는 "1.0" 불필요
print(e.get())

5. Listbox : 다중선택 (활용 예제에서 핵심) insert,delete,get +  size 와 curselection

listbox = Lixtbox(root, selectmode="extended", height=0) # 0은 다 보임
listbox.pack()

listbox.insert(0, "사과")
listbox.insert(END, "포도")
listbox.delete(0)
listbox.size()
listbox.get(0,2) # 0~2까지 내용 get
listbox.curselection() # 현재 selection한 index 반환

6. Checkbox : variable

chkvar = IntVar()
chkbox = Checkbutton(root, text="오늘 하루 보지 않기", variable=chkvar)
chkbox.select() # 자동선택
chkbox.deselect() # 선택해제

chkvar.get()

7. Radiobox : 체크박스가 네/아니오면, Radiobox 는 객관식 --> get.variable() 은 동일

8. Combobox : 활용예제에서 옵션값, Radiobox 가 접혀져있는 형태. -->여러개의 values 

values = [str(i) for i in range(1,32)]
# values 에 여러 개의 value 를 리스트형으로 만든다.
combobox = ttk.Combobox(root, height=5, values=values)
combobox.pack()

combobox.set("카드 결제일")
combobox.current(0) # 첫번째 인덱스

impot tkinter.ttk as ttk

9 progressbar : 활용예제에서 작업단위로 진행률 표시. 

활용예제

for idx, img in enumerate(images):
    result_img.paste(img, (0, y_offset))
    y_offset += img.size[1]
    
    progress = (idx+1) / len(images) * 100
    p_var.set(progress)
    progress_bar.update()

사용 예시

p_var2 = DoubleVar()
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) # progress bar 의 값 설정
        progressbar2.update() # ui 업데이트
        print(p_var2.get())

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

10 Menu 클래스: add_command(), add_separator(), add_radiobutton(), add_checkbutton()

menu = Menu(root)

 

menu_file = Menu(menu, tearoff=0)

menu.add_cascade(label="파일", menu=menu_file) # menu에 추가한다. 추가할 메뉴는 menu_file

 

menu_sub = Menu(menu_file, tearoff=0)

menu_file.add_cascade(label="파일", menu=menu_sub) #menu_file 에 추가한다. 추가할 메뉴는 menu_sub


from tkinter import *

root = Tk()
root.title("Nado 메뉴")
root.geometry("640x480+900+100")

menu = Menu(root) # 최상단 루트바
#############################

# File 메뉴 : add_command()
def create_file():
    print("새 파일 만들기")

menu_file = Menu(menu, tearoff=0) #tearoff 메뉴분리
menu_file.add_command(label="새파일", command=create_file)
menu_file.add_command(label="새창")
menu_file.add_separator()
menu.add_cascade(label="파일", menu=menu_file)


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

 

# menu_file 의 하위에 추가
menu_sub = Menu(menu_file, tearoff=0)
menu_file.add_cascade(label="하위lang추가", menu=menu_sub)

 

# 라디오버튼 : add_radiobutton()

menu_lang = Menu(menu, tearoff=0)

menu_lang.add_radiobutton(label="파이썬")

menu_lang.add_radiobutton(label="자바")

menu.add_cascade(label="라디오버튼" menu=menu_lang)

 

# 체크버튼 : add_checkbutton()

menu_agree = Menu(menu, tearoff=0)

menu_lang.add_checkbutton(label="동의?")

menu.add_cascade(label="체크버튼" menu=menu_agree)


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

11 messagebox

12 frame

13 scrollbar : 프레임 안에, Listbox 가 있고, Listbox 오른쪽에 스크롤바 만들기

** 리스트박스 내 스크롤처리, 리스트박스 우측세로바 스크롤처리, 둘 다 해줘야함.

(위 이미지는 우측 스크롤바 처리 안한 상태 ) scrollbar.config(command=listbox.yview)

frame = Frame(root)
frame.pack()

#프레임안에 스크롤바,리스트바 넣기. Scrollbar(frmae), Listbox(frame)
scrollbar = Scrollbar(frame) 
scrollbar.pack(side="right", fill="y")

# listbox = Listbox(frame)
listbox = Listbox(frame, selectmode="extended", height=10, yscrollcommand = scrollbar.set)
for i in range(1,32):
    listbox.insert(END, str(i) + "일")
listbox.pack(side="left") #좌 리스트박스, 우 스크롤바

scrollbar.config(command=listbox.yview) # 스크롤바 직접 드래그시(매핑)

14 grid : 계산기

15 quiz : 메모장

  • 글쓰기 영역 txt = Text()
    txt = Text(root, yscrollcommand=scrollbar.set) # 리스트박스
    txt.pack(side="left", fill="both", expand=True)
    scrollbar.config(command=txt.yview) # 리스트박스 y 스크롤바
  • 파일열기 동작 : 파일이 있는지 체크,
    if os.path.isfile(filename):
  •  파일 오픈 주의 사항!
    with open() 사용시, txt.delete("1.0", END) 후, txt.insert(END, file.read())
    txt.delete() 없으면, 현재 작성한 내용 뒤에, 기존 내용이 append 됨
import os
from tkinter import *

root = Tk()
root.title("제목 없음 - Windows 메모장")
root.geometry("640x480") # 가로 * 세로

# 열기, 저장 파일 이름
filename = "mynote.txt"

def open_file():
    if os.path.isfile(filename): # 파일 있으면 True, 없으면 False
        with open(filename, "r", encoding="utf8") as file:
            txt.delete("1.0", END) # 텍스트 위젯 본문 삭제
            txt.insert(END, file.read()) # 파일 내용을 본문에 입력

def save_file():
    with open(filename, "w", encoding="utf8") as file:
        file.write(txt.get("1.0", END)) # 모든 내용을 가져와서 저장

menu = Menu(root)

menu_file = Menu(menu, tearoff=0)
menu_file.add_command(label="열기", command=open_file)
menu_file.add_command(label="저장", command=save_file)
menu_file.add_separator()
menu_file.add_command(label="끝내기", command=root.quit)
menu.add_cascade(label="파일", menu=menu_file)

# 편집, 서식, 보기, 도움말
menu.add_cascade(label="편집")
menu.add_cascade(label="서식")
menu.add_cascade(label="보기")
menu.add_cascade(label="도움말")

# 스크롤 바
scrollbar = Scrollbar(root)
scrollbar.pack(side="right", fill="y")

# 본문 영역
txt = Text(root, yscrollcommand=scrollbar.set)
txt.pack(side="left", fill="both", expand=True)
scrollbar.config(command=txt.yview)

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

Project

댓글