tkinter 는파이썬에서그래픽사용자인터페이스 (GUI: graphical user interface) 를개발할때필요한모듈
tkinter 는예전부터유닉스계열에서사용되던 Tcl/Tk 위에객체지향계층을입힌것이다. Tk 는 John Ousterhout 에의하여 Tcl 스크립팅언어를위한 GUI 확장으로개발
from tkinter import * window = Tk() label = Label(window, text="hello World!") label.pack() window.mainloop()
from tkinter import * window = Tk() b1 = Button(window, text=" 이것이파이썬버튼입니다.") b1.pack() window.mainloop()
from tkinter import * window = Tk() b1 = Button(window, text=" 첫번째버튼 ") b2 = Button(window, text=" 두번째버튼 ") b1.pack() b2.pack() window.mainloop()
from tkinter import * window = Tk() b1 = Button(window, text=" 첫번째버튼 ") b2 = Button(window, text=" 두번째버튼 ") b1.pack(side=left) b2.pack(side=left) window.mainloop()
from tkinter import * window = Tk() b1 = Button(window, text=" 첫번째버튼 ") b2 = Button(window, text=" 두번째버튼 ") b1.pack(side=left,padx=10) b2.pack(side=left,padx=10) window.mainloop()
from tkinter import * window = Tk() b1 = Button(window, text=" 첫번째버튼 ") b2 = Button(window, text=" 두번째버튼 ") b1.pack(side=left,padx=10) b2.pack(side=left,padx=10) b1["text"] = "One" b2["text"] = "Two" window.mainloop()
tkinter 프로그램은이벤트에기반을두고동작된다.
from tkinter import * def callback(): button["text"] =" 버튼이클릭되었음!" window = Tk() button = Button(window, text=" 클릭 ", command=callback) button.pack(side=left) window.mainloop()
from tkinter import * window = Tk() label = Label(window, text=" 안녕하세요!") label.pack() button = Button(window, text="tkinter 로버튼을쉽게만들수있습니다.") button.pack() window.mainloop()
from tkinter import * class App: def init (self ): window = Tk() hellob = Button(window, text="hello", command=self.hello, fg="red") hellob.pack(side=left) quitb = Button(window, text="quit", command=self.quit) quitb.pack(side=left) window.mainloop() def hello(self): print("hello 버튼이클릭되었음!") def quit(self): print("quit 버튼이클릭되었음!") App()
Button Canvas Checkbutton Entry Frame Label Listbox Menu Menubutton Message Radiobutton Scale Scrollbar Text Toplevel LabelFrame PanedWindow Spinbox
Grid 격자배치관리자 (grid geometry manager) 는테이블형태의배치 Pack 압축배치관리자 (pack geometry manager) 는위젯들을부모위젯안에압축 Place 절대배치관리자 (place geometry manager) 는주어진위치에위젯을배치
색상 : 부분의위젯은배경 (bg) 과전경 (fg) 변수를사용하여위젯및텍스트색상을지정 from tkinter import * window = Tk() button = Button(window, text=" 버튼을클릭하세요 ") button.pack() button["fg"] = "yellow" button["bg"] = "green"
사용자에게색상을선택하게한다. from tkinter import * color=colorchooser.askcolor() print(color)
폰트를튜플로지정할수있는데여기에는 ( 폰트이름, 폰트의크기, 폰트스타일 ) 과같은형식을사용한다. ("Times", 10, "bold") ("Helvetica", 10, "bold italic") ("Symbol", 8) 문자열로도지정 w = Label(master, text="helvetica", font="helvetica 16 )
import tkinter as tk import tkinter.font as font class App: def init (self): root=tk.tk() self.customfont = font.font(family="helvetica", size=12) buttonframe = tk.frame() label = tk.label(root, text="hello, World!", font=self.customfont) buttonframe.pack() label.pack() bigger = tk.button(root, text=" 폰트를크게 ", command=self.bigfont) smaller = tk.button(root, text=" 폰트를작게 ", command=self.smallfont) bigger.pack() smaller.pack()
root.mainloop() def BigFont(self): size = self.customfont['size'] self.customfont.configure(size=size+2) def SmallFont(self): size = self.customfont['size'] self.customfont.configure(size=size-2) app=app()
from tkinter import * window = Tk() photo = PhotoImage(file="a1.gif") w = Label(window, image=photo) w.photo = photo w.pack() window.mainloop()
from tkinter import * window = Tk() photo = PhotoImage(file="wl.gif") w = Label(window, image=photo).pack(side="right") message= """ 삶이그대를속일지라도슬퍼하거나노하지말라! 우울한날들을견디면 : 믿으라, 기쁨의날이오리니. 마음은미래에사는것현재는슬픈것 : 모든것은순간적인것, 지나가는것이니그리고지나가는것은훗날소중하게되리니. """ w2 = Label(window, justify=left, padx = 10, text=message).pack(side="left") window.mainloop()
from tkinter import * window = Tk() Label(window, text="times Font 폰트와빨강색을사용합니다.", fg = "red", font = "Times 32 bold italic").pack() Label(window, text="helvetica 폰트와녹색을사용합니다.", fg = "blue", bg = "yellow", font = "Helvetica 32 bold italic").pack() window.mainloop()
from tkinter import * window = Tk() Label(window, text=" 이름 ").grid(row=0) Label(window, text=" 나이 ").grid(row=1) e1 = Entry(window) e2 = Entry(window) e1.grid(row=0, column=1) e2.grid(row=1, column=1) window.mainloop( )
from tkinter import * def show(): print(" 이름 : %s\n 나이 : %s" % (e1.get(), e2.get())) parent = Tk() Label(parent, text=" 이름 ").grid(row=0) Label(parent, text=" 나이 ").grid(row=1) e1 = Entry(parent) e2 = Entry(parent) e1.grid(row=0, column=1) e2.grid(row=1, column=1) Button(parent, text=' 보이기 ', command=show).grid(row=3, column=1, sticky=w, pady=4) Button(parent, text=' 종료 ', command=parent.quit).grid(row=3, column=0, sticky=w, pady=4) mainloop( )
from tkinter import * window = Tk() T = Text(window, height=5, width=60) T.pack() T.insert(END, " 테스트위젯은여러줄의 \n 텍스트를표시할수있습니다.") mainloop()
수식을텍스트로입력하면이것을평가하고그결과를출력할수있는간단한계산기를작성하여본다. 수식의형식은파이썬과동일하여야한다. eval() 함수를사용하여사용자가입력한수식을계산할수있다.
from tkinter import * from math import * def calculate(event): label.configure(text = " 결과 : " + str(eval(entry.get()))) window = Tk() Label(window, text=" 파이썬수식입력 :").pack() entry = Entry(window) entry.bind("<return>", calculate) entry.pack() label = Label(window, text =" 결과 :") label.pack() w.mainloop()
Canvas 위젯을이용하여그래프를그린다거나그래픽에디터를작성할수도있고많은종류의커스텀위젯을작성할수있다.
from tkinter import * window = Tk() w = Canvas(window, width=300, height=200) w.pack() w.create_rectangle(50, 25, 200, 100, fill="blue") w.create_line(0, 0, 300, 200) w.create_line(0, 0, 300, 100, fill="red") mainloop()
호 (arc) 비트맵 (bitmap, 내장파일이나 XBM 파일형식 ) 이미지 (image, BitmapImage나 PhotoImage 객체 ) 직선 (line) 타원 (oval, 원이나타원 ) 다각형 (polygon) 사각형 (rectangle) 텍스트 (text) 윈도우 (window)
윈도우를하나만들고여기에랜덤한크기의사각형을여러개그려보자. 위치도랜덤이어야하고크기, 색상도랜덤으로하여본다.
import random from tkinter import * window = Tk() canvas = Canvas(window, width=500, height=400) canvas.pack() color = ["red", "orange", "yellow", "green", "blue", "violet"] def draw_rect(): x = random.randint(0, 500) y = random.randint(0, 400) w = random.randrange(100) h = random.randrange(100) canvas.create_rectangle(x, y, w, h, fill = random.choice(color)) for i in range(10): draw_rect() window.mainloop()
from tkinter import * window = Tk() canvas = Canvas(window, width=300, height=200) canvas.pack() canvas.create_oval(10, 10, 200, 150) window.mainloop()
from tkinter import * window = Tk() canvas = Canvas(window, width=300, height=200) canvas.pack() canvas.create_arc(10, 10, 200, 150, extent=90, style=arc) window.mainloop()
from tkinter import * window = Tk() canvas = Canvas(window, width=300, height=200) canvas.pack() canvas.create_polygon(10, 10, 150, 110, 250, 20, fill="blue") window.mainloop()
from tkinter import * window = Tk() canvas = Canvas(window, width=300, height=200) canvas.pack() canvas.create_text(100, 100, text=' 싱스트리트 (Sing Street)') mainloop()
from tkinter import * window = Tk() canvas = Canvas(window, width=300, height=200) canvas.pack() img = PhotoImage(file="D:\\starship.png") canvas.create_image(20, 20, anchor=nw, image=img) mainloop()
import time from tkinter import * window = Tk() canvas = Canvas(window, width=400, height=300) canvas.pack() id=canvas.create_oval(10, 100, 50, 150, fill="green") for i in range(100): canvas.move(id, 3, 0) window.update() time.sleep(0.05)
from tkinter import * window = Tk() canvas = Canvas(window, width=400, height=300) canvas.pack() id=canvas.create_oval(10, 100, 50, 150, fill="green") def move_right(event): canvas.move(id, 5, 0) canvas.bind_all('<keypress-right>', move_right)
다음과같이마우스를움직여서화면에그림을그리는애플리케이션을작성해보자.
from tkinter import * w = 500 h = 300 def drawdot( event ): x1, y1 = ( event.x - 1 ), ( event.y - 1 ) x2, y2 = ( event.x + 1 ), ( event.y + 1 ) canvas.create_oval( x1, y1, x2, y2, fill = "red" ) window = Tk() canvas = Canvas(window, width=w, height=h) canvas.pack(expand = YES, fill = BOTH) canvas.bind( "<B1-Motion>", drawdot ) message = Label( window, text = " 마우스를드래그하면점들이그려집니다." ) message.pack( side = BOTTOM ) window.mainloop()
라디오버튼 (radio button) 은체크박스와비슷하지만하나의그룹안에서는한개의버튼만선택할수있다는점이다르다.
from tkinter import * window = Tk() choice = IntVar() Label(window, text=" 가장선호하는프로그래밍언어를선택하시오 ", justify = LEFT, padx = 20).pack() Radiobutton(window, text="python", padx = 20, variable=choice, value=1).pack(anchor=w) Radiobutton(window, text="c", padx = 20, variable=choice, value=2).pack(anchor=w) Radiobutton(window, text="java", padx = 20, variable=choice, value=3).pack(anchor=w) Radiobutton(window, text="swift", padx = 20, variable=choice, value=4).pack(anchor=w) window.mainloop()
체크박스 (check box) 란사용자가클릭하여서체크된상태와체크되지않은상태중의하나로만들수있는위젯이다.
from tkinter import * window = Tk() Label(window, text=" 선호하는언어를모두선택하시오 :").grid(row=0, sticky=w) value1 = IntVar() Checkbutton(window, text="python", variable=value1).grid(row=1, sticky=w) value2 = IntVar() Checkbutton(window, text="c", variable=value2).grid(row=2, sticky=w) value3 = IntVar() Checkbutton(window, text="java", variable=value3).grid(row=3, sticky=w) value4 = IntVar() Checkbutton(window, text="swift", variable=value4).grid(row=4, sticky=w) window.mainloop()
from tkinter import * window = Tk() lb = Listbox(window, height=4) lb.pack() lb.insert(end,"python") lb.insert(end,"c") lb.insert(end,"java") lb.insert(end,"swift")
배치관리자는컨테이너안에존재하는위젯의크기와위치를자동적으로관리하는객체이다.
격자배치관리자 (grid geometry manager) 는위젯 ( 버튼, 레이블등 ) 을테이블형태로배치한다. from tkinter import * window = Tk() b1 = Button(window, text="one") b2 = Button(window, text="two") b1.grid(row=0, column=0) b2.grid(row=1, column=1) window.mainloop()
격자배치관리자 (grid geometry manager) 는위젯 ( 버튼, 레이블등 ) 을테이블형태로배치한다. from Tkinter import * window = Tk() Label(window, text=" 박스 #1", bg="red", fg="white").pack() Label(window, text=" 박스 #2", bg="green", fg="black").pack() Label(window, text=" 박스 #3", bg="blue", fg="white").pack() window.mainloop()
격자배치관리자 (grid geometry manager) 는위젯 ( 버튼, 레이블등 ) 을테이블형태로배치한다. from tkinter import * window = Tk() w = Label(window, text=" 박스 #1", bg="red", fg="white") w.place(x=0, y=0) w = Label(window, text=" 박스 #2", bg="green", fg="black") w.place(x=20, y=20) w = Label(window, text=" 박스 #3", bg="blue", fg="white") w.place(x=40, y=40) window.mainloop()
Tic-Tac-Toe 는 3 3 칸을가지는게임판을만들고, 경기자 2 명이동그라미심볼 (O) 와가위표심볼 (X) 을고른다. 경기자는번갈아가며게임판에동그라미나가위표를놓는다. 가로, 세로, 대각선으로동일한심볼을먼저만들면승리하게된다.
from tkinter import * # i 번째버튼을누를수있는지검사한다. 누를수있으면 X 나 O 를표시한다. def checked(i): global player button = list[i] # 리스트에서 I 번째버튼객체를가져온다. # 버튼이초기상태가아니면이미누른버튼이므로아무것도하지않고리턴한다. if button["text"]!= " ": return button["text"] = " " + player+" " button["bg"] = "yellow" if player=="x": player = "O" button["bg"] = "yellow" else : player = "X" button["bg"] = "lightgreen"
window = Tk() # 윈도우를생성한다. player="x" # 시작은플레이어 X이다. list = [] # 9개의버튼을생성하여격자형태로윈도우에배치한다. for i in range(9): b = Button(window, text=" ", command=lambda k=i: checked(k)) b.grid(row=i//3, column=i%3) list.append(b) # 버튼객체를리스트에저장한다. window.mainloop()
격자배치관리자를사용하여레이블과버튼을배치한다. 색상의개수만큼반복하면서레이블과버튼을생성하고격자형태로배치하면된다.
from tkinter import * 약간의 3 차원효과를낸다. window = Tk() colors = ['green', 'red', 'orange','white','yellow','blue'] r = 0 for c in colors: Label(window, text=c, relief=ridge, width=15).grid(row=r, column=0) Button(window, bg=c, width=10).grid(row=r, column=1) r = r + 1 window.mainloop()
레이블을사용하여간단한스톱워치를작성하여보자. 시작버튼을누르면시작되고중지버튼을누르면스톱워치가중지된다.
import tkinter as tk def starttimer(): if (running): global timer timer += 1 timetext.configure(text=str(timer)) window.after(10, starttimer) def start(): global running running = True def stop(): global running running = False running = False
window = tk.tk() timer = 0 timetext = tk.label(window, text="0", font=("helvetica", 80)) timetext.pack() startbutton = tk.button(window, text=' 시작 ', bg="yellow", command=start) startbutton.pack(fill=tk.both) stopbutton = tk.button(window, text=' 중지 ', bg="yellow", command=stop) stopbutton.pack(fill=tk.both) starttimer() window.mainloop()
파이썬을이용하여버튼을가지는계산기를작성하여보자. 적절한배치관리자를선택하여사용하라.
from tkinter import * def click(key): if key == '=': # = 버튼이면수식을계산하여결과를표시한다. try: result = eval(entry.get()) entry.delete(0, END) entry.insert(end, str(result)) except: entry.insert(end, " 오류!") elif key == 'C': entry.delete(0, END) else: entry.insert(end, key) window = Tk() window.title(" 간단한계산기 ")
buttons = [ '7', '8', '9', '+', 'C', '4', '5', '6', '-', ' ', '1', '2', '3', '*', ' ', '0', '.', '=', '/', ' ' ] # 반복문으로버튼을생성한다. i=0 for b in buttons: cmd = lambda x=b: click(x) b = Button(window,text=b,width=5,relief='ridge',command=cmd) b.grid(row=i//5+1,column=i%5) i += 1 # 엔트리위젯은맨윗줄의 5 개의셀에걸쳐서배치된다. entry = Entry(window, width=33, bg="yellow") entry.grid(row=0, column=0, columnspan=5) window.mainloop()
window = Tk() def callback(event): print(event.x, event.y, " 에서마우스이벤트발생 ") frame = Frame(window, width=100, height=100) frame.bind("<button-1>", callback) frame.pack() window.mainloop() 32 44 에서마우스이벤트발생 6 52 에서마우스이벤트발생
from tkinter import * window = Tk() def key(event): print ( repr(event.char), " 가눌렸습니다. ") def callback(event): frame.focus_set() print(event.x, event.y, " 에서마우스이벤트발생 ") frame = Frame(window, width=100, height=100) frame.bind("<key>", key) frame.bind("<button-1>", callback) frame.pack() window.mainloop() 66 31 에서마우스이벤트발생 'k' 가눌렸습니다.
<Button-1> <B1-Motion> <ButtonRelease-1> <Double-Button-1> <Enter> <Leave> <FocusIn> <FocusOut> <Return> <Key> a <Shift-Up> <Configure>
from tkinter import * def sleft(event): print(" 단일클릭, 왼쪽버튼 ") def dleft(event): print(" 더블클릭, 왼쪽버튼 ") widget = Button(None, text=' 마우스클릭 ') widget.pack() widget.bind('<button-1>', sleft) widget.bind('<double-1>', dleft) widget.mainloop() 단일클릭, 왼쪽버튼단일클릭, 왼쪽버튼더블클릭, 왼쪽버튼
from tkinter import * def motion(event): print(" 마우스위치 : (%s %s)" % (event.x, event.y)) return window = Tk() message = """ 당신스스로가하지않으면아무도당신의운명을개선시켜주지않을것이다. """ msg = Message(window, text = message) msg.config(bg='yellow',fg='blue', font="times 20 italic") msg.bind('<motion>',motion) msg.pack() window.mainloop() 마우스위치 : (274 45) 마우스위치 : (271 55) 마우스위치 : (270 69)
사용자가컴퓨터가생성한숫자 (1 부터 100 사이의난수 ) 를알아맞히는게임을그래픽사용자인터페이스를사용하여제작해보자.
from tkinter import * import random answer = random.randint(1,100) def guessing(): guess = int(guessfield.get()) if guess > answer: msg = " 높음!" elif guess < answer: msg = " 낮음!" else: msg = " 정답!" resultlabel["text"] = msg guessfield.delete(0, 5)
def reset(): global answer answer = random.randint(1,100) resultlabel["text"] = " 다시한번하세요!" window = Tk() window.configure(bg="white") window.title(" 숫자를맞춰보세요!") window.geometry("500x80") titlelabel = Label(window, text=" 숫자게임에오신것을환영합니다!", bg="white") titlelabel.pack()
guessfield = Entry(window) guessfield.pack(side="left") trybutton = Button(window, text=" 시도 ", fg="green", bg="white", command=guessing ) trybutton.pack(side="left") resetbutton = Button(window, text=" 초기화 ", fg="red", bg="white", command=reset) resetbutton.pack(side="left") resultlabel = Label(window, text="1 부터 100 사이의숫자를입력하시오.", bg="white") resultlabel.pack(side="left") window.mainloop()
tkinter 에서는먼저루프윈도우를생성하고레이블이나버튼을생성할때첫번째인수로윈도우를넘기면된다. 파이썬은 3 종류의배치관리자를제공한다. 압축 (pack) 배치관리자, 격자 (grid) 배치관리자. 절대 (place) 배치관리자가바로그것이다. 위젯에이벤트를처리하는함수를연결하려면 bind() 메소드를사용한다. 예를들면 widget.bind('<button-1>', sleft) 와같이하면된다.