Tkinter 튜토리얼-레이아웃 관리
이전 섹션에서 우리는 label
, button
, 드롭 다운 메뉴 등과 같은 몇 가지 Tkinter 위젯 유형을 소개했습니다. 이것이 Tkinter 의 지오메트리 관리 방법-이 섹션에서 배울 핵심 사항입니다.
Tkinter 에는 3 가지 지오메트리 관리 방법, 즉 pack
,grid
및 place
가 있습니다. 하나씩 살펴 보겠습니다.
Tkinter pack
레이아웃 방법
pack
메소드는 문자 그대로 표시된대로 위젯을 작성한 후 창 프레임에 위젯을 패킹합니다. 모든 pack
옵션이 나열되어있는 Tkinter Label 섹션에서이 레이아웃 방법을 소개합니다.
pack
메소드를 사용하여 위젯을 레이아웃하는 방법을 보여줄 것이다. 몇 가지 예는 올바른 구성을 보여줍니다.
Tkinter pack
레이아웃-상대 위치
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West", width=15)
buttonW.pack(side="left")
buttonE = tk.Button(app, text="East", width=15)
buttonE.pack(side="right")
app.mainloop()
프로그램을 실행하면 다음과 같은 창이 나타납니다.
보시다시피,buttonWest
는 창의 왼쪽에 스냅되고 buttonEast
는 창의 오른쪽에 스냅됩니다. 아래 창 크기를 조절할 수는 있지만 여전히 창 측면에 달라 붙어 상대 위치는 변하지 않습니다.
buttonW.pack(side="left")
side
에는 네 가지 옵션이 있습니다-
top
bottom
left
right
위젯을 창의 ‘측면’에 배치합니다. 예제에서 보듯이,side='left'
때문에 buttonW
가 창의 왼쪽에 할당되고 side='right'
때문에 buttonE
가 창의 오른쪽에 있습니다.
이제 흥미로운 시나리오가 있습니다. 두 개의 위젯에 동일한 side
속성이 있으면 어떻게됩니까?
직접 대답하거나 다음 코드를 실행하여 확인하십시오.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West", width=15)
buttonW.pack(side="left")
buttonE1 = tk.Button(app, text="East 1", width=15)
buttonE1.pack(side="right")
buttonE2 = tk.Button(app, text="East 2", width=15)
buttonE2.pack(side="right")
app.mainloop()
위젯 내부 및 외부 패딩을 추가하는 Tkinter pack
경우에 따라 위젯 내부와 외부에 약간의 패딩을 추가하여 위젯 사이와 위젯 텍스트와 위젯 경계 사이에 혼잡이 줄어 듭니다. 이제 padx
, pady
,ipadx
및 ipadx
와 같은 옵션이 필요합니다.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West")
buttonW.pack(side="left", ipadx=20, padx=30)
buttonE = tk.Button(app, text="East")
buttonE.pack(side="right", ipadx=20, padx=30)
app.mainloop()
두 버튼 모두 x
에 내부 20 단위 패딩과 외부 30 단위를 추가하며 단위는 픽셀이지만 한 문자의 너비는 아닙니다.
x, y 방향으로 채우는 Tkinter pack
레이아웃
다음 코드 구현은 창과 동일한 너비 또는 높이로 위젯 차원을 자동으로 채울 수 있으며 창을 확대 / 축소하면 컨트롤의 크기가 창 크기에 따라 자동으로 변경 될 수 있습니다.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonX = tk.Button(app, text="Fill X", bg="red", height=5)
buttonX.pack(fill="x")
buttonY = tk.Button(app, text="Fill Y", bg="green", width=10)
buttonY.pack(side="left", fill="y")
app.mainloop()
butonX.pack(fill = 'x')
는 buttonX
가 전체 창의 너비를 채울 것임을 의미합니다. 마찬가지로 fill = 'y'
는 전체 창의 높이를 채우고 fill ='both'
는 너비와 높이를 모두 채 웁니다.
Tkinter pack
레이아웃 옵션 expand
-자동 확장
fill=
옵션 위의 창 크기가 수정되면 자동으로 위젯이 x
및 / 또는 y
방향으로 채워집니다. 또 다른 유사한 요구 사항은 위젯에 목록과 같은 여러 옵션이 포함되어 있으면 모든 내용을 자동으로 표시하는 방법입니다.
import tkinter as tk
import calendar
app = tk.Tk()
buttonX = tk.Button(app, text="Label ", bg="blue", height=5)
buttonX.pack(fill="x")
listboxA = tk.Listbox(app, width=10)
listboxA.pack(fill="both", expand=1)
for i in range(1, 13):
listboxA.insert(tk.END, calendar.month_name[i])
app.mainloop()
expand = True
또는 expand = 1
인 경우, 목록 상자는 위의 예에서 설명한 것처럼 1 월부터 12 월까지 모든 항목을 나열합니다.
expand
가 False
로 설정되면, 목록 상자는 기본적으로 처음 10 개의 항목 만 표시합니다. 목록 상자를 선택한 후 숨겨진 항목을 표시하려면 마우스 또는 방향 키를 사용해야합니다.
listboxA.pack(fill="both", expand=0)
expand = 0
은 목록 상자를 비활성화하여 모든 항목을 자동으로 표시합니다.
Tkinter grid
레이아웃 방법
Tkinter grid
는 또 다른 가장 중요한 레이아웃 지오메트리 방법입니다. 이것은 모든 지오메트리 관리자 중 하나의 단일 방법 만 배우려는 경우에 알아야하는 방법입니다.
그리드는 종종 대화 상자에서 사용되며 그리드의 위치 좌표에 따라 위젯을 배치 할 수 있습니다. ‘그리드’레이아웃 방법은 모든 위젯의 안정적인 상대 위치를 가질 수 있습니다.
다음 예제는 위의 예제와 비교하여 비교적 복잡한 GUI 를 생성하며, 다음 섹션에서 설명 할 가능한 많은 그리드 옵션을 사용합니다.
import tkinter as tk
app = tk.Tk()
labelWidth = tk.Label(app, text="Width Ratio")
labelWidth.grid(column=0, row=0, ipadx=5, pady=5, sticky=tk.W + tk.N)
labelHeight = tk.Label(app, text="Height Ratio")
labelHeight.grid(column=0, row=1, ipadx=5, pady=5, sticky=tk.W + tk.S)
entryWidth = tk.Entry(app, width=20)
entryHeight = tk.Entry(app, width=20)
entryWidth.grid(column=1, row=0, padx=10, pady=5, sticky=tk.N)
entryHeight.grid(column=1, row=1, padx=10, pady=5, sticky=tk.S)
resultButton = tk.Button(app, text="Get Result")
resultButton.grid(column=0, row=2, pady=10, sticky=tk.W)
logo = tk.PhotoImage(file="python.gif")
labelLogo = tk.Label(app, image=logo)
labelLogo.grid(
row=0,
column=2,
columnspan=2,
rowspan=2,
sticky=tk.W + tk.E + tk.N + tk.S,
padx=5,
pady=5,
)
app.mainloop()
Tkinter grid
column
및 row
옵션
labelWidth.grid(column=0, row=0, ipadx=5, pady=5, sticky=tk.W + tk.N)
모든 위젯은 ‘그리드’레이아웃 방법으로 절대 셀에 배치됩니다. 셀 좌표는 열과 행에 의해 결정됩니다.
labelWidth
위젯은(0, 0)
위치의 셀에 배치됩니다. 좌표는 창의 왼쪽 상단에서 시작합니다.
ipadx
,ipady
,padx
및 pady
옵션은 pack
방법과 동일합니다.
Tkinter grid
sticky
옵션
sticky
는 위젯이 셀보다 작은 경우 위젯이 셀에 고정되는 방식을 결정합니다.
sticky |
의미 |
---|---|
W |
왼쪽에 붙어 |
E |
오른쪽에 붙어 |
N |
상단에 붙어 |
S |
바닥에 붙이다 |
기본 sticky
옵션은 가운데, 즉 W + E + N + S
입니다.
Tkinter columnspan
및 rowspan
옵션
labelLogo.grid(
row=0,
column=2,
columnspan=2,
rowspan=2,
sticky=tk.W + tk.E + tk.N + tk.S,
padx=5,
pady=5,
)
labelLogo
의 셀 좌표는(column = 2, row = 0)
이고 로고의 크기는 비교적 크기 때문에 2x2
의 셀 크기로 할당됩니다. columnspan = 2
및 rowspan = 2
는 위젯이 위젯의 위치에서 시작하여 X
및 Y
방향으로 두 셀에 걸쳐 있음을 의미합니다.
Tkinter place
방법
Tkinter place
메소드는 창에서 위젯을 절대 또는 상대 위치에 배치합니다. 우리는 여전히이 레이아웃 방법의 옵션을 소개하기 위해 위와 같은 접근법을 사용합니다.
import tkinter as tk
app = tk.Tk()
app.geometry("300x300")
labelA = tk.Label(app, text="Label (0, 0)", fg="blue", bg="#FF0")
labelB = tk.Label(app, text="Label (20, 20)", fg="green", bg="#300")
labelC = tk.Label(app, text="Label (40, 50)", fg="black", bg="#f03")
labelD = tk.Label(app, text="Label (0.5, 0.5)", fg="orange", bg="#0ff")
labelA.place(x=0, y=0)
labelB.place(x=20, y=20)
labelC.place(x=40, y=50)
labelD.place(relx=0.5, rely=0.5)
app.mainloop()
Tkinter ‘place’절대 위치
labelA.place(x=0, y=0)
labelB.place(x=20, y=20)
place
의 x =
및 y =
옵션은 단위가 픽셀 인 위젯의 절대 위치를 결정합니다. 예를 들어,lableB.place(x = 20, y = 20)
는 labelB
가(20, 20)
의 좌표에 배치됨을 의미합니다.
Tkinter place
상대 위치
절대 위치의 단점은 상대 위치가있는 창에 다른 위젯이있는 경우 창을 확대 / 축소 할 때 절대 위치 레이아웃을 사용하는 위젯이 다른 위젯과 겹칠 수 있다는 것입니다.
place
레이아웃 방법에는 상대 위치 옵션, 즉
labelD.place(relx=0.5, rely=0.5)
relx
와 rely
는 0.0 ~ 1.0
의 범위에 있습니다. 창 크기에 대한 위젯 위치의 상대적 백분율입니다.
예를 들어,relx = 0.5, rely = 0.5
는 위젯이 창 너비의 50 %와 창 높이의 50 %에 배치됨을 의미합니다.
relx = 1.0
은 창의 오른쪽 경계이고,rely = 1.0
은 창의 아래쪽 경계입니다.
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook