728x90
728x170
윈도우 프로그래밍(Window Programming)
기본 위젯 활용
기본 윈도우 창의 구성
- 위젯(Widget) : 윈도창에 나올 수 있는 문자, 버튼, 체크박스, 라디오 버튼 등
- Tk()
- TK Interface 의 약어
- Tcl/Tk 라는 전통적인 GUI 인터페이스 윈도우, 리눅스, 맥 등에서 모두 동일한 코드로 사용 가능하다.
- 기본이 되는 윈도우를 반환한다.
- 루트 윈도우 또는 베이스 윈도우 라고 한다.
from tkinter import *
window = Tk()
## 이 부분에서 화면을 구성하고 처리 ##
window.mainloop()
윈도우 창 조절
from tkinter import *
window = Tk()
window.title("윈도우 창 연습") # 윈도우 창에 제목 표시
window.geometry("400x100") # 윈도우 창의 초기 크기를 400x100 으로 지정
window.resizable(width = FALSE, height = FALSE) # 가로와 세로의 크기가 변경되지 않도록 지정
window.mainloop()
레이블
- 레이블(Label) : 문자를 표현할 수 있는 위젯
- Label() 함수가 레이블을 만들어 주고, pack() 함수로 해당 레이블을 한 화면에 표시한다.
- font : 글꼴과 크기 지정
- fg : foreground의 약어로, 글자색을 지정
- bg : background의 약어로 배경색을 지정
- width 와 height : 위젯의 폭과 높이 지정
- anchor : 위젯이 어느 위치에 자리 잡을지 결정
from tkinter import *
window = Tk()
label1 = Label(window, text = "안녕하세요~")
label2 = Label(window, text = "열심히", font = ("궁서체", 30), fg = "blue")
label3 = Label(window, text = "공부 중입니다.", bg = "magenta", width = 20, height = 5, anchor = SE)
label1.pack()
label2.pack()
label3.pack()
window.mainloop()
레이블에 글자 대신 이미지 넣기
- PhotoImage() 함수를 사용하여 레이블에 글자 대신 이미지를 넣을 수 있다.
- GIF 파일만 지원하고 JPEG나 BMP 등은 지원하지 않는다.
from tkinter import *
window = Tk()
photo = PhotoImage(file = "gif/dog.gif")
label1 = Label(window, image = photo)
label1.pack()
window.mainloop()
버튼
- 버튼(Button) : 마우스로 클릭하면 눌리는 효과와 함께 지정한 작업 실행하는 위젯
예 : 버튼을 누르면 파이썬 IDLE이 종료되는 코드
from tkinter import *
window = Tk()
button1 = Button(window, text = "파이썬 종료", fg = "red", command = quit)
button1.pack()
window.mainloop()
예 : 이미지 버튼을 누르면 간단한 메시지 창이 나오는 코드
from tkinter import *
from tkinter import messagebox # messagebox 모듈 사용
def myFunc() :
messagebox.showinfo("강아지 버튼", "강아지가 귀엽죠? ^^") # showinfo(제목, 내용)
window = Tk()
photo = PhotoImage(file = "gif/dog2.gif")
button1 = Button(window, image = photo, command = myFunc)
button1.pack()
window.mainloop()
체크 버튼
- 체크 버튼(Check Button) : 켜고 끄는 데 사용하는 위젯
from tkinter import *
from tkinter import messagebox
window = Tk()
def myFunc() :
if chk.get() == 0 :
messagebox.showinfo("", "체크버튼이 꺼졌어요.")
else :
messagebox.showinfo("", "체크버튼이 켜졌어요.")
chk = IntVar()
cb1 = Checkbutton(window, text = "클릭하세요", variable = chk, command = myFunc)
cb1.pack()
window.mainloop()
라디오 버튼
- 라디오 버튼(Radio Button) : 여러 개 중에서 하나를 선택하는 데 사용하는 위젯
from tkinter import *
window = Tk()
def myFunc() :
if var.get() == 1 :
label1.configure(text = "파이썬")
elif var.get() == 2 :
label1.configure(text = "C++")
else :
label1.configure(text = "Java")
var = IntVar()
rb1 = Radiobutton(window, text = "파이썬", variable = var, value = 1, command = myFunc)
rb2 = Radiobutton(window, text = "C++", variable = var, value = 2, command = myFunc)
rb3 = Radiobutton(window, text = "Java", variable = var, value = 3, command = myFunc)
label1 = Label(window, text = "선택한 언어 : ", fg = "red")
rb1.pack()
rb2.pack()
rb3.pack()
label1.pack()
window.mainloop()
위젯의 배치와 크기 조절
수평 정렬
- pack() 함수의 옵션 중, side=LEFT, RIGHT 를 사용한다.
from tkinter import *
window = Tk()
button1 = Button(window, text = "버튼1")
button2 = Button(window, text = "버튼2")
button3 = Button(window, text = "버튼3")
button1.pack(side = LEFT)
button2.pack(side = LEFT)
button3.pack(side = LEFT)
window.mainloop()
- 리스트(List)와 for 문을 활용하여 사용할 수 있다.
from tkinter import *
window = Tk()
btnList = [None] * 3
for i in range(0, 3) :
btnList[i] = Button(window, text = "버튼" + str(i + 1))
for btn in btnList :
btn.pack(side = RIGHT)
window.mainloop()
수직 정렬
- pack() 함수의 옵션 중, side=TOP, BOTTOM 을 사용한다.
from tkinter import *
window = Tk()
btnList = [None] * 3
for i in range(0, 3) :
btnList[i] = Button(window, text = "버튼" + str(i + 1))
for btn in btnList :
btn.pack(side = TOP)
window.mainloop()
from tkinter import *
window = Tk()
btnList = [None] * 3
for i in range(0, 3) :
btnList[i] = Button(window, text = "버튼" + str(i + 1))
for btn in btnList :
btn.pack(side = BOTTOM)
window.mainloop()
폭 조정
- pack() 함수의 옵션 중, fill=X 를 사용한다.
from tkinter import *
window = Tk()
btnList = [None] * 3
for i in range(0, 3) :
btnList[i] = Button(window, text = "버튼" + str(i + 1))
for btn in btnList :
btn.pack(side = TOP, fill = X)
window.mainloop()
위젯 사이의 여백 조정
- pack() 함수의 옵션 중, padx=픽셀값 또는 pady=픽셀값 을 사용한다.
from tkinter import *
window = Tk()
btnList = [None] * 3
for i in range(0, 3) :
btnList[i] = Button(window, text = "버튼" + str(i + 1))
for btn in btnList :
btn.pack(side = TOP, fill = X, padx = 10, pady = 10)
window.mainloop()
위젯 내부의 여백 조정
- pack() 함수의 옵션 중, ipadx=픽셀값 또는 ipady=픽셀값 을 사용한다.
from tkinter import *
window = Tk()
btnList = [None] * 3
for i in range(0, 3) :
btnList[i] = Button(window, text = "버튼" + str(i + 1))
for btn in btnList :
btn.pack(side = TOP, fill = X, ipadx = 10, ipady = 10)
window.mainloop()
예 : 위젯의 내부와 외부에 모두 여백 지정
from tkinter import *
window = Tk()
btnList = [None] * 3
for i in range(0, 3) :
btnList[i] = Button(window, text = "버튼" + str(i + 1))
for btn in btnList :
btn.pack(side = TOP, fill = X, ipadx = 10, ipady = 10, padx = 10, pady = 10)
window.mainloop()
고정된 위치에 배치
- 위젯을 고정된 위치에 배치하려면 pack() 함수 대신 place() 함수를 사용하면 된다.
from tkinter import *
btnList = [None] * 9
fnameList = ["froyo.gif", "gingerbread.gif", "honeycomb.gif", "icecream.gif", "jellybean.gif",
"kitkat.gif", "lollipop.gif", "marshmallow.gif", "nougat.gif"]
photoList = [None] * 9
i, k = 0, 0
xPos, yPos = 0, 0
num = 0
window = Tk()
window.geometry("210x210")
for i in range(0, 9) :
photoList[i] = PhotoImage(file = "gif/" + fnameList[i])
btnList[i] = Button(window, image = photoList[i])
for i in range(0, 3) :
for k in range(0, 3) :
btnList[num].place(x = xPos, y = yPos) # place(x, y) 함수 사용
num += 1
xPos += 70
xPos = 0
yPos += 70
window.mainloop()
프로그램 구현 : <이전> 버튼이나 <다음> 버튼을 누르면 사진들을 표시하는 사진 앨범 프로그램
from tkinter import *
from time import *
fnameList = ["jeju1.gif", "jeju2.gif", "jeju3.gif", "jeju4.gif", "jeju5.gif",
"jeju6.gif", "jeju7.gif", "jeju8.gif", "jeju9.gif"]
photoList = [None] * 9
num = 0
## 함수 선언 부분 ##
def clickNext() :
global num
num += 1
if num > 8 :
num = 0
photo = PhotoImage(file = "gif/" + fnameList[num])
pLabel.configure(image = photo)
pLabel.image = photo
def clickPrev() :
global num
num -= 1
if num < 0 :
num = 8
photo = PhotoImage(file = "gif/" + fnameList[num])
pLabel.configure(image = photo)
pLabel.image=photo
window = Tk()
window.geometry("700x500")
window.title("사진 앨범 보기")
btnPrev = Button(window, text = "<< 이전", command = clickPrev)
btnNext = Button(window, text = "다음 >>", command = clickNext)
photo = PhotoImage(file = "gif/" + fnameList[0])
pLabel = Label(window, image = photo)
btnPrev.place(x = 250, y = 10)
btnNext.place(x = 400, y = 10)
pLabel.place(x = 15, y = 50)
window.mainloop()
키보드와 마우스 이벤트 처리
마우스 이벤트
마우스 동작 | 마우스 버튼 | 이벤트 코드 |
클릭할 때 | 모든 버튼 공통 | <Button> |
왼쪽 버튼 | <Button-1> | |
가운데 버튼 | <Button-2> | |
오른쪽 버튼 | <Button-3> | |
떼었을 때 | 모든 버튼 공통 | <ButtonRelease> |
왼쪽 버튼 | <ButtonRelease-1> | |
가운데 버튼 | <ButtonRelease-2> | |
오른쪽 버튼 | <ButtonRelease-3> | |
더블 클릭할 때 | 모든 버튼 공통 | <Double-Button> |
왼쪽 버튼 | <Double-Button-1> | |
가운데 버튼 | <Double-Button-2> | |
오른쪽 버튼 | <Double-Button-3> | |
드래그할 때 | 왼쪽 버튼 | <B1-Motion> |
가운데 버튼 | <B2-Motion> | |
오른쪽 버튼 | <B3-Motion> | |
마우스 커서가 위젯 위로 올라왔을 때 | <Enter> | |
마우스 커서가 위젯에서 떠났을 때 | <Leave> |
- 마우스 이벤트 처리 형식
def 이벤트처리함수(event) :
# 이 부분에 마우스 이벤트가 발생할 때 동작할 내용 작성
위젯.bind("마우스이벤트", 이벤트처리함수)
예 : 마우스 왼쪽 버튼을 클릭했을 때 처리하는 방법
from tkinter import *
from tkinter import messagebox
def clickLeft(event) :
messagebox.showinfo("마우스", "마우스 왼쪽 버튼이 클릭됨")
window = Tk()
window.bind("<Button-1>", clickLeft)
window.mainloop()
예 : 지정된 위젯을 클릭했을 때 다른 함수 호출
from tkinter import *
from tkinter import messagebox
def clickImage(event) :
messagebox.showinfo("마우스", "토끼에서 마우스가 클릭됨")
window = Tk()
window.geometry("400x400")
photo = PhotoImage(file = "gif/rabbit.gif")
label1 = Label(window, image = photo)
label1.bind("<Button>", clickImage)
label1.pack( expand = 1, anchor = CENTER)
window.mainloop()
더보기
- 이미지를 클릭할 때만 이벤트가 처리된다. (window.bind() 가 아닌 label1.bind() 를 사용했기 때문)
- <Button> 이벤트를 사용했기 때문에 어떤 마우스 버튼을 눌러도 메시지 창이 표시된다.
예 : 마우스를 클릭할 때마다 어떤 마우스 버튼이 클릭되었는지 보여주고 클릭한 좌표 출력
from tkinter import *
def clickMouse(event) :
txt = ""
if event.num == 1 :
txt += "마우스 왼쪽 버튼이 ("
elif event.num == 3 :
txt += "마우스 오른쪽 버튼이 ("
txt += str(event.y) + "," + str(event.x) + ")에서 클릭됨"
label1.configure(text = txt)
window = Tk()
window.geometry("400x400")
label1 = Label(window, text = "이곳이 바뀜")
window.bind("<Button>", clickMouse)
label1.pack(expand = 1, anchor = CENTER)
window.mainloop()
키보드 이벤트
키보드 동작 | 이벤트 코드 |
모든 키를 누를 때 | <Key> |
특수 키를 누를 때 | <Return>, <BackSpace>, <Tab>, <Shift_L>, <Control_L>, <Alt_L>, <Pause>, <Caps_Lock>, <Escape>, <End>, <Home>, <Left>, <Right>, <Up>, <Down>, <Num_Lock>, <Delete>, <F1>~<F12> 등 |
일반 키를 누를 때 | a~z, A~Z, 0~9, <space>, <less> |
화살표 키와 조합 | <Shift-Up>, <Shift-Down>, <Shift-Left>, <Shift-Right> 등 |
- Enter 를 처리하려면 <Return> 을 사용한다.
- 대소문자 등도 구분해서 처리 가능하다.
- 일반 키를 누를 때 주의할 점
- SpaceBar는 <Space>로, < 는 <less>로 사용한다.
- 키보드 이벤트는 위젯에서 키보드가 눌리면 발생한다.
from tkinter import *
from tkinter import messagebox
def keyEvent(event) :
messagebox.showinfo("키보드 이벤트", "눌린 키 : " + chr(event.keycode)) # event.keycode에는 숫자값이 들어 있음.
window = Tk()
window.bind("<Key>", keyEvent)
window.mainloop()
메뉴와 대화상자
메뉴의 생성
- 메뉴의 구성 개념도와 형식
메뉴자체 = Menu(부모윈도우)
부모윈도우.config(menu = 메뉴자체)
상위메뉴 = Menu(메뉴자체)
메뉴자체.add_cascade(label = "상위메뉴텍스트", menu = 상위메뉴)
상위메뉴.add_command(label = "하위메뉴1", command = 함수1)
상위메뉴.add_command(label = "하위메뉴2", command = 함수2)
예 : [파일] 메뉴 아래에 [열기]와 [종료] 하위 메뉴가 있는 코드
from tkinter import *
window = Tk()
mainMenu = Menu(window)
window.config(menu = mainMenu)
fileMenu = Menu(mainMenu)
mainMenu.add_cascade(label = "파일", menu = fileMenu)
fileMenu.add_command(label = "열기")
fileMenu.add_separator()
fileMenu.add_command(label = "종료")
window.mainloop()
예 : 메뉴를 선택하면 작동할 수 있도록 코드 추가하기
from tkinter import *
from tkinter import messagebox
def func_open() :
messagebox.showinfo("메뉴 선택", "열기 메뉴를 선택함")
def func_exit() :
window.quit()
window.destroy()
window = Tk()
mainMenu = Menu(window)
window.config(menu=mainMenu)
fileMenu = Menu(mainMenu)
mainMenu.add_cascade(label = "파일", menu = fileMenu)
fileMenu.add_command(label = "열기", command = func_open) # command 옵션 사용
fileMenu.add_separator()
fileMenu.add_command(label = "종료", command = func_exit) # command 옵션 사용
window.mainloop()
대화상자의 생성과 사용
- tkinter.simpledialog 모듈을 임포트한 후, askinteger() 및 askstring() 등을 사용한다.
from tkinter import *
from tkinter.simpledialog import *
window = Tk()
window.geometry("400x100")
label1 = Label(window, text = "입력된 값 : ")
label1.pack()
value = askinteger("확대 배수", "주사위 숫자(1~6)을 입력하세요", minvalue = 1, maxvalue = 6)
label1.configure(text = str(value))
window.mainloop()
예 : 그림 파일인 GIF 파일을 선택하는 코드
from tkinter import *
from tkinter.filedialog import *
window = Tk()
window.geometry("400x100")
label1 = Label(window, text = "선택된 파일 이름 ")
label1.pack()
filename = askopenfilename(parent = window, filetypes = (("GIF 파일", "*.gif"), ("모든 파일", "*.*")))
label1.configure(text=str(filename))
window.mainloop()
예 : 그림 파일인 GIF 파일을 저장하는 코드
from tkinter import *
from tkinter.filedialog import *
window = Tk()
window.geometry("400x100")
label1 = Label(window, text = "입력된 값 : ")
label1.pack()
saveFp = asksaveasfile(parent = window, mode = "w", defaultextension = ".jpg", filetypes = (("JPG 파일", "*.jpg;*.jpeg"), ("모든 파일", "*.*")))
label1.configure(text = saveFp)
saveFp.close()
window.mainloop()
프로그램 구현 : 명화 감상 프로그램 만들기
from tkinter import *
from tkinter.filedialog import *
def func_open() :
filename = askopenfilename(parent = window, filetypes = (("GIF 파일", "*.gif"), ("모든 파일", "*.*")))
photo = PhotoImage(file = filename)
pLabel.configure(image = photo)
pLabel.image = photo
def func_exit() :
window.quit()
window.destroy()
window = Tk()
window.geometry("500x500")
window.title("명화 감상하기")
photo = PhotoImage()
pLabel = Label(window, image = photo)
pLabel.pack(expand=1, anchor = CENTER)
mainMenu = Menu(window)
window.config(menu = mainMenu)
fileMenu = Menu(mainMenu)
mainMenu.add_cascade(label = "파일", menu = fileMenu)
fileMenu.add_command(label = "파일 열기", command = func_open)
fileMenu.add_separator()
fileMenu.add_command(label = "프로그램 종료", command = func_exit)
window.mainloop()
728x90
그리드형(광고전용)
'Programming > Python' 카테고리의 다른 글
[Python] 파이썬에서 외부 모듈 등록 방법 (sys.path.append, PYTHONPATH) (0) | 2023.04.11 |
---|---|
[Jupyter Notebook] 주피터 노트북을 다크모드로 변경하기 (5) | 2022.06.07 |
[Python] 파이썬을 이용하여 함수 그래프 그리기 (NumPy, matplotlib.pyplot) (0) | 2022.04.12 |
[Python] 튜플(Tuple) (0) | 2022.03.19 |
[Python] 문자열 (0) | 2022.03.19 |
[Python] 세트(Set) (0) | 2022.03.19 |
[Python] 딕셔너리(Dictionary) (0) | 2022.03.19 |
[Python] 리스트(List) (0) | 2022.03.19 |