"Life is too short, You need python"
Tkinter에서 생성하는 위젯들은 해당 위젯 syntax 사용 후 html의 close tag와 같이 pack(), grid(), place() 3가지 Geometry Manager 중 하나를 선택해 닫아줘야 비로소 parent 위젯에 배치가 됩니다. 배치 메커니즘이 상이하여 UI 구성이나 개인 성향에 따라 선호되는 Manager가 있을 수 있고 pack - grid와 같이 혼용이 되지 않는 경우가 있어 UI를 원하는 형태로 디자인하기 위해 더 적합하고 효율적인 Geometry Manager를 선택하는 것은 매우 중요합니다. 그렇기 때문에 위젯들의 사용법에 앞서 Layout Manager 들의 사용법과 속성에 대해 먼저 알아보도록 하겠습니다. 그 첫 시간으로 pack manager입니다.
pack ( 상대 위치 배치 )
pack은 사용하기 가장 쉬운 레이아웃 관리자입니다. 위젯의 정확한 좌표가 아닌 상대적 위치에 대해 선언합니다.
그렇기 때문에 직관적이지 못하고 절대 위치 지정 기능을 제공하는 place() 및 grid()에 비해 정밀도가 낮고 제한적입니다. 직관적이지 않은 탓에 사용법에 익숙하지 않다면 원하는 대로 배치하는 것이 다소 까다로울 수 있지만 사용법을 잘 익혀 둔다면 다른 두 Geometry Manager보다 많이 사용하실 거라 생각합니다. 개인적으로도 가장 선호하는 방식입니다.
왼쪽, 오른쪽, 위쪽, 아래쪽 위치로 제한된 수평 및 수직 Box 형태의 공간에 위젯을 채워 넣듯 배치합니다. 각 Box는 오프셋 되고 서로에 대해 상대적입니다. 위젯 간 상대적인 위치에 영향을 많이 받는다는 점을 기억하세요.
Syntax
widget.pack(option parameters)
- 사용할 위젯 변수에 .pack()을 사용함으로써 배치가 됩니다.
- .pack() 순서에 따라 위젯 간 배치 우선순위가 결정이 되기 때문에 순서가 매우 중요합니다.
- option parameters를 통해 위젯의 공간 할당, 위젯 간 간격, 내부 text의 배치 등을 결정합니다.
- pack은 grid와 함께 사용할 수 없으며 place와는 함께 사용할 수 있습니다.
( Input )
import tkinter as tk
root = tk.Tk()
root.title('PY Life')
root.geometry("300x200")
Button_1 = tk.Button(root, text = "Button 1")
Button_2 = tk.Button(root, text = "Button 2")
Button_3 = tk.Button(root, text = "Button 3")
Button_4 = tk.Button(root, text = "Button 4")
Button_5 = tk.Button(root, text = "Button 5")
Button_1.pack()
Button_2.pack()
Button_3.pack()
Button_4.pack()
Button_5.pack()
root.mainloop()
( Output )
별도 옵션이 없다면 위의 그림과 같이 출력이 됩니다.
(side = 'top')이 기본 옵션이기 때문에 위에서 아래로 위젯이 쌓입니다.
Option Parameters
pack()에 옵션을 추가해야 원하는 형태로 배치가 가능하며 가능한 옵션은 다음과 같습니다. 무엇보다 많은 경험과 시행착오를 거쳐야 자신만의 배치 방법을 찾을 수 있을 테니 많이 사용해 보시길 권장드립니다.
이름 |
의미 | 기본값 | 속성 |
side | 상위 위젯 내 특정 위치로 공간 할당 | top | top, bottom, left, right |
anchor | 할당된 공간 내에서 위치 지정 | center | center, n, e, s, w, ne, nw, se, sw |
fill | 할당된 공간에 대한 크기 맞춤 | none | none, x, y, both |
expand | 미사용 공간 확보(확장) | False | Boolean |
ipadx | 위젯에 대한 x 방향 내부 패딩 | 0 | 상수 |
ipady | 위젯에 대한 y 방향 내부 패딩 | 0 | 상수 |
padx | 위젯에 대한 x 방향 외부 패딩 | 0 | 상수 |
pady | 위젯에 대한 y 방향 외부 패딩 | 0 | 상수 |
Option 1 . side / fill / expand
pack()은 side로 상/하/좌/우 기본 position을 잡고, fill과 expand 옵션으로 원하는 만큼의 공간을 확장합니다.
- side : pack 순서에 따라 옵션에 정의된 위치로 위젯의 공간을 할당받습니다.
- fill : 할당된 공간을 지정된 속성에 따라 최대 크기로 맞춥니다.
- expand : 할당된 공간 외 사용 가능한 미사용 중인 공간까지 확장합니다.
아래의 예시를 통해 내용을 보도록 하겠습니다.
( Input )
import tkinter as tk
root = tk.Tk()
root.title('PY Life')
root.geometry("300x200")
Button_1 = tk.Button(root, text = 'Button 1', bg = 'green')
Button_2 = tk.Button(root, text = 'Button 2', bg = 'red')
Button_3 = tk.Button(root, text = 'Button 3', bg = 'blue')
Button_4 = tk.Button(root, text = 'Button 4', bg = 'yellow')
Button_5 = tk.Button(root, text = 'Button 5', bg = 'pink')
Button_6 = tk.Button(root, text = 'Button 6', bg = 'purple')
Button_1.pack(side = 'left')
Button_2.pack(side = 'left')
Button_3.pack(side = 'left')
Button_4.pack() # Default는 side = 'top'
Button_5.pack(side = 'bottom')
Button_6.pack(side = 'right')
( Output )
side 옵션 외 별도의 옵션이 없다면 위와 같은 형태로 배치가 됩니다.
위젯 사이즈에 대한 정의가 없어 padx/pady/ipadx/ipady가 0인 상태라 위젯들이 다소 무질서하게 배치되어 있는 것으로 보일 수 있지만 사실은 아래와 같이 공간을 잠정적으로 점유하고 있다고 생각하시면 됩니다.
fill 옵션을 both로 세팅하면 해당 위젯이 차지하는 공간을 확인할 수 있습니다.
Button 6 expand 옵션을 Default로 두면 폭이 Button 1 ~ 3와 동일한 형태로 빈 공간이 나타나지만
최대 Button 4의 공간만큼 차지할 수 있음을 보여드리기 위해 expand = True 옵션을 추가했습니다.
( Input )
Button_1.pack(side = 'left', fill = 'both')
Button_2.pack(side = 'left', fill = 'both')
Button_3.pack(side = 'left', fill = 'both')
Button_4.pack(side = 'top', fill = 'both')
Button_5.pack(side = 'bottom', fill = 'both')
Button_6.pack(side = 'right', fill = 'both', expand = True)
( Output )
여기서 Button 4의 순서를 Button 1 다음으로 바꿔볼까요?
( Input )
Button_1.pack(side = 'left', fill = 'both')
Button_4.pack(side = 'top', fill = 'both') #
Button_2.pack(side = 'left', fill = 'both')
Button_3.pack(side = 'left', fill = 'both')
Button_5.pack(side = 'bottom', fill = 'both')
Button_6.pack(side = 'right', fill = 'both', expand = True)
( Output )
위에서 보실 수 있듯이 Button 4가 Button 2에 앞서 공간을 점유한 것을 보실 수 있습니다.
pack은 순서가 중요하다, 또한 우선순위에 따라 공간을 점유한다
이 두 가지만 명심하신다면 쉽게 이해하시고 좀 더 자유롭게 배치하실 수 있으실 겁니다.
Option 2. padx / pady / ipadx / ipady
padx / pady는 위젯 외부 공간에 대한 Gap 정의이고, ipadx / ipady는 위젯 내부 공간에 대한 Gap 정의입니다.
( Input )
import tkinter as tk
root = tk.Tk()
root.title('PY Life')
root.geometry("300x200")
Button_1 = tk.Button(root, text = 'Button 1', bg = 'green')
Button_2 = tk.Button(root, text = 'Button 2', bg = 'red')
Button_3 = tk.Button(root, text = 'Button 3', bg = 'blue')
Button_4 = tk.Button(root, text = 'Button 4', bg = 'yellow')
Button_5 = tk.Button(root, text = 'Button 5', bg = 'pink')
Button_6 = tk.Button(root, text = 'Button 6', bg = 'purple')
Button_7 = tk.Button(root, text = 'Button 6', bg = 'gold')
Button_1.pack(side = 'left')
Button_2.pack(side = 'left', ipadx = 15, ipady = 5)
Button_3.pack(side = 'top')
Button_4.pack(side = 'top', padx = 10, pady = 10)
Button_5.pack(side = 'bottom')
Button_6.pack(side = 'right')
Button_7.pack(side = 'right', padx = 10, pady = 10)
root.mainloop()
( Output )
Button 1과 Button 2의 차이는 ipadx / ipady입니다. 위젯 내부에 text에 대한 공간이 할당되는데
Button 1은 위젯과 위젯 내부 텍스트 공간과 간격이 default인 0 상태를 보여줍니다.
Button 2는 ipadx / ipady를 통해 간격이 설정되며 위젯 크기가 커졌습니다.
Button 3과 Button 4, Button 6과 Button 7은 각각 padx, pady에 의해 외부 간격이 발생한 것을 보여 줍니다.
@ padx / pady / ipadx / ipady의 screen units에 대한 내용은 추후 포스팅을 통해 상세히 알아보도록 하겠습니다.
Option 3. anchor
anchor는 할당된 공간 내 특정 위치로 배치합니다.
마무리
Geometry Manager 중 pack 사용법에 대해 알아보았습니다.
'PYTHON > tkinter' 카테고리의 다른 글
(Python Tkinter) Chapter 6. Button ( 버튼 ) (0) | 2022.09.13 |
---|---|
(Python Tkinter) Chapter 5. Label ( 레이블 ) (0) | 2022.09.08 |
(Python Tkinter) Chapter 4. place - Geometry(Layout) Managers (0) | 2022.07.28 |
(Python Tkinter) Chapter 3. grid - Geometry(Layout) Managers (0) | 2022.07.28 |
(Python Tkinter) Chapter 1. GUI 생성 (0) | 2022.06.25 |