목차

<title>TK 파이썬</title>

시작

레퍼런스 - 시작

그외

tkinter의 낡은 모양새가 싫은 경우 써볼만한 다른 GUI lib

모듈 import

import tkinter
# or
from tkinter import *

이외의 추가 모듈

tkinter.scrolledtext 수직스크롤바가 포함된 텍스트 윈도우
tkinter.colorchooser 색상 선택 다이얼로그
tkinter.commondialog 다른 다이얼로그의 베이스 클래스
tkinter.filedialog 파일에 대한 공용 다이얼로그
tkinter.font 폰트
tkinter.messagebox tk 표준 다이얼로그 사용
tkinter.simpledialog 기본적인 다이얼로그와 편의 기능(?)
tkinter.dnd drag and drop
turtle 터틀(タートル)그래픽 (?) 제공

최소 앱

#!/usr/bin/env python
import tkinter as tk
import tkinter.messagebox as mbx
 
class CApp(tk.Frame) :
    def __init__(self, master=None):
        super().__init__(master)
        self.pack()
        self.create_widgets()
 
    def create_widgets(self):
        self.quitBtn = tk.Button(self, text="Quit", command=self.quit)
        self.quitBtn.pack(side='bottom')
    def sayHi(self):
        mbx.showinfo("INFO","메시지입니다")
 
root = tk.Tk( )
root.title('Window Title')
app = CApp(master=root)
app.mainloop()

Window Geometry(지오메트리)

레퍼런스

Tk 에서는 윈도우의 크기와 위치정보를 지오메트리(Geometry)라고 부르고, 아래 형식으로 입력한다.

<color green>width</color>x<color green>height</color>±<color green>x</color>±<color green>y</color>

#위의 코드에 조금 덧붙여서
root = tk.Tk( )
root.geometry('300x200+5+40') 
app = CApp(master=root)
app.mainloop()

Resize

window.resizable(FALSE, FALSE)
window.minsize(200,100)
window.maxsize(500,500)

Get WidgetSize

위젯을 사이즈를 얻고 싶은데, 화면에 반영되지 않아 결과가 <color /silver>1×1</color> 처럼 나온다면,

위젯.update_idletasks()
# or
위젯.update()

화면 갱신이 필요한데 아직 안되었을때 , 쓰면 될듯. 이런거 윈도우에도 있었던 것 같은데..

Anchor

Packer

pack tutorial

tk ppt

위젯이 있을 위치를 정해서 배치하는 것. pack() 함수를 실행하면 옵션에 따라 위젯을 배치한다.

some_widget.pack() # default 는 'top'
some_widget.pack(side='left')
some_widget.pack(expand=1)

pack()을 호출해주면, 위에서 아래 방향으로 순서대로 배열된다.크기는 각자 조정.

Packer 옵션

anchor 위젯의 중심이겠지. <color /silver>'n'</color> <color /silver>'s'</color> <color /silver>'w'</color> <color /silver>'e'</color> 같은값을 사용한다
exapand 불 값으로 <color /silver>0</color> 이나 <color /silver>1</color>을 쓴다. fill 과 같이 사용하면 채울 수 있다.
fill <color /silver>'x'</color>, <color /silver>'y'</color>, <color /silver>'both'</color>, <color /silver>'none'</color>
늘어나는 방향을 설정.
ipadx, ipady 슬레이브위젯의 내부 패딩을 설정
padx, pady 슬레이브위젯 외부의 패딩값을 설정
side 값은 <color /silver>'left'</color>, <color /silver>'right'</color>, <color /silver>'top'</color>, <color /silver>'bottom'</color> 이고 위젯의 배열 방향을 설정한다.
import tkinter as tk
root = tk.Tk()
 
# 테스트용 Frame()을 만들고 구분하기 위해 레드로 설정
frame = tk.Frame(root) 
frame['bg'] = 'red'
 
# pack()을 써보자, 샘플 전부
# frame.pack(fill='both', expand=1, side='left')
 
# 테스트1
frame.pack(fill='both') # 바로 채워질줄 알았는데, 위에 가로만 늘어나고 세로는 작은 한줄정도만
# 테스트2
frame.pack(fill='both', expand=1) # expand를 넣으니 꽉찬 상태로 위젯이 표시되었다.
 
# 새로운 위젯 추가 구분하기 위해 블루 설정
frame2 = tk.Frame(root)
frame2['bg'] = 'blue'
 
# 두번째 위젯을 추가해서 배열하면 어떻게 나오나?
 
# 실패: 이렇게 배열하면 두번째꺼 안보임, 두번째거가 살짝 한줄만
frame.pack(fill='both', expand=1)
frame2.pack()
 
# 실패: 이렇게 해도 두번째꺼 안보임
frame.pack(fill='both', expand=1)
frame2.pack(fill='both')
 
# 성공: 이렇게 하니 위에서 아래로 배열
frame.pack(fill='both', expand=1)
frame2.pack(fill='both', expand=1)
 
# 실패: 좌->우 방향이 되려면. 두번째꺼가 안보임
frame.pack(fill='both', expand=1, side='left')
frame2.pack(fill='both', expand=1)
 
# 성공: 좌->우 방향이 되려면. 두번째꺼가 안보임
frame.pack(fill='both', expand=1, side='left')
frame2.pack(fill='both', expand=1, side='left')
 
#frame2.pack(fill='both',  expand=1, side='right') #샘플
root.title('Title')
root.geometry('640x400+5+40')
root.mainloop()

이것처럼 만들어보기.

f1 = tk.Frame(root)
f1['bg'] = 'red'
f2 = tk.Frame(root)
f2['bg'] = 'blue'
f21 = tk.Frame(f2)
f21['bg'] = 'yellow'
f22 = tk.Frame(f2)
f22['bg'] = 'green'
 
f1.pack(fill='both', expand=1) 
f2.pack(fill='both', expand=1, padx=4, pady=4)
f21.pack(fill='both', expand=1, side='left') 
f22.pack(fill='both', expand=1, side='left') 

Pack으로 Frame 안쪽을 정 가운데 정렬하기

<color /silver>expand</color>, <color /silver>fill</color>을 쓰라고 .. (아직 안해봐서)

대상오브젝트.pack(fill="none", expand=True)

Grid

화면 분할. 레퍼런스

좀 더 도움이 되는 문서 http://foster-johnson.com/grid.html

사용되기 전에, 어떻게 분할 것인지 미리 정의해두면 거기에 맞게 배열된다.

초기화를 따로 하진 않고, grid() 함수가 쓰일때마다 최대 값을 알아서 설정하는 듯하다.

샘플1

윈도우 크기만큼 자식 위젯이 늘어나는 grid 배열 예

import tkinter as tk
import random
 
root = tk.Tk()
 
def get_rand_color():
  de=("%02x"%random.randint(0,255))
  re=("%02x"%random.randint(0,255))
  we=("%02x"%random.randint(0,255))
  color="#"+de+re+we
  return color
 
def grid_test3():
  for r in range(3):
    if r != 1: 
      root.grid_rowconfigure(r, weight=1)
    for c in range(4):
      if r == 0:
        root.grid_columnconfigure(c, weight=1)
      tv = tk.Label(root, text='[R%s/C%s]'%(r,c))
      tv['bg'] = get_rand_color()
      gd = tv.grid(row=r,column=c, sticky='nsew')
 
root.title('Title') # 타이틀 적고
root.geometry('300x200+5+40') # 윈도우 크기 정하고
grid_test3()
root.mainloop()

샘플2

xx.grid(column=0, row=0) # 0,0 위치에 배열
xx.grid(column=3, row=0, columnspan=2) # 컬럼 3번째에서부터 2칸 연속 사용
# row 쪽은 rowspan 을 사용해서 가로지르기를 구현한다.

from tkinter import *
from tkinter import ttk
 
root = Tk()
 
content = ttk.Frame(root)
frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100)
namelbl = ttk.Label(content, text="Name")
name = ttk.Entry(content)
 
onevar = BooleanVar()
twovar = BooleanVar()
threevar = BooleanVar()
onevar.set(True)
twovar.set(False)
threevar.set(True)
 
one = ttk.Checkbutton(content, text="One", variable=onevar, onvalue=True)
two = ttk.Checkbutton(content, text="Two", variable=twovar, onvalue=True)
three = ttk.Checkbutton(content, text="Three", variable=threevar, onvalue=True)
ok = ttk.Button(content, text="Okay")
cancel = ttk.Button(content, text="Cancel")
 
content.grid(column=0, row=0)
frame.grid(column=0, row=0, columnspan=3, rowspan=2)
namelbl.grid(column=3, row=0, columnspan=2)
name.grid(column=3, row=1, columnspan=2)
one.grid(column=0, row=3)
two.grid(column=1, row=3)
three.grid(column=2, row=3)
ok.grid(column=3, row=3)
cancel.grid(column=4, row=3)
 
root.mainloop()

Grid로 Frame 가운데 정렬

따로 옵션이 없고, grid를 3×3 으로 설정해서 가운데 배치되도록 하는 방법으로.

# 3x3 그리드 사용. configure()로 하는거 없이 그냥 비중 설정만해서 있는 것으로 세팅한다.
오브젝트.grid(row=1, column=1)
부모오브젝트.grid_rowconfigure(0, weight=1)
부모오브젝트.grid_rowconfigure(2, weight=1)
부모오브젝트.grid_columnconfigure(0, weight=1)
부모오브젝트.grid_columnconfigure(2, weight=1)

윈도우매니져

폰트

from tkinter import font
 
def some_func():
  font = font.Font(famaily='Helvetica', size=13)
 
# 어딘가에서 쓰기 

기본 폰트를 변경

정해진 기본폰트 (Tcl Fonts)

TkDefaultFont The default for all GUI items not otherwise specified.
TkTextFont Used for entry widgets, listboxes, etc.
TkFixedFont A standard fixed-width font.
TkMenuFont The font used for menu items.
TkHeadingFont The font typically used for column headings in lists and tables.
TkCaptionFont A font for window and dialog caption bars.
TkSmallCaptionFont A smaller caption font for subwindows or tool dialogs
TkIconFont A font for icon captions.
TkTooltipFont A font for tooltips.

TkDefaultFont 를 바꿔보자

from tkinter import font
 
default_font = font.nametofont("TkDefaultFont") # 기본 폰트 가져와서
default_font.configure(family='Arial', size=13) # 설정 변경

Frame

<color black/lightgray>padding</color> 옵션은 <color black/lightgray>ttk.Frame</color> 을 위한 것. <color black/lightgray>tkinter.Frame</color>라면 <color black/lightgray>padx</color>, <color black/lightgray>pady</color> 를 써야한다.