별의 공부 블로그 🧑🏻‍💻
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
그리드형(광고전용)
⚠️AdBlock이 감지되었습니다. 원할한 페이지 표시를 위해 AdBlock을 꺼주세요.⚠️


📖 Contents 📖