본문 바로가기
GUI 튜토리얼/tkinter 한꼬집씩만 따라해보기

22. 프레임 위젯 - 위젯들을 묶어주는 위젯

by 일코 2022. 11. 20.

지난 포스팅

2022.11.18 - [기타/tkinter 한꼬집씩만 따라해보기] - 21. 스크롤바 기본제공 텍스트 위젯 - Scrolledtext

 

21. 스크롤바 기본제공 텍스트 위젯 - Scrolledtext

지난 포스팅 2022.11.18 - [기타/tkinter 한꼬집씩만 따라해보기] - 20. 텍스트박스 만들기 20. 텍스트박스 만들기 지난 포스팅 2022.11.18 - [기타/tkinter 한꼬집씩만 따라해보기] - 19. 라디오버튼 선택에 따

martinii.fun


 

이번 포스팅에서는 : 위젯들을 묶어주는 프레임 위젯

지금까지 tkinter의 기본적인 위젯 사용법을 주로 다루었습니다.

어느 정도 GUI가 커지고, 위젯이 많이 들어가는 경우에,

코딩에 도움이 되는 몇 가지 툴이 있습니다.

대표적으로 세 가지만 꼽자면 프레임, 디자이너, OOP 등이 있는데요.

(다른 툴에 대해서도 차차 다루겠지만)

이번 포스팅에서는 tkinter의 위젯주머니, Frame 위젯에 대해 소개합니다.

Frame은 익숙하게 보이는 위젯이지만, 의식하지 않으면 눈에 잘 띄지도 않습니다.

아래 노란 형광펜으로 표시한 요소가 Frame위젯입니다. (정확히는 Frame과 거의 유사한 LabelFrame입니다.)

먼저 ttk.LabelFrame 위젯을 생성하고 나서

다른 위젯, 예를 들면 레이블이나 콤보박스 등을 생성할 때

위젯의 master를 해당 LabelFrame위젯으로 설정하면 해당 LabelFrame 안으로 위젯이 들어가게 됩니다.

ttk.LabelFrame 대신 ttk.Frame을 사용하셔도 됩니다.
프레임 상단 좌측에 프레임의 제목이 없는 것 말고는 아무 차이가 없습니다.

아래는 LabelFrame의 기본적인 예시코드입니다.

import tkinter as tk
from tkinter import ttk

win = tk.Tk()
win.title("페이지 설정")

label_frame1 = tk.LabelFrame(win, text=" 용지 ")
label_frame1.grid(row=0, column=0, padx=10, pady=10, ipadx=10, ipady=10)

ttk.Label(label_frame1, text="크기(Z):    ").grid(row=0, column=0, padx=10, pady=10)
ttk.Label(label_frame1, text="공급(S):    ", state="disabled").grid(row=1, column=0)

ttk.Combobox(label_frame1, values=["A3", "A4", "A5"], state="readonly").grid(row=0, column=1, padx=10, pady=10)
ttk.Combobox(label_frame1, values=[], state="disabled").grid(row=1, column=1)

win.mainloop()

 

실행해보면

실행화면을 보시면 작은 네모 안에 위젯들이 위치하고 있어서,

위젯들끼리 그룹으로 묶어 표시하기 좋다는 점을 알 수 있습니다.

 

프레임은 위젯들을 구조화하여 시각적으로 보기 좋게 표현할 수 있을 뿐만 아니라,

그룹 위젯들의 대표 타이틀을 따로 지정할 수 있기 때문에(레이블프레임) 맥락의 파악이 쉽다는 장점이 있습니다.

내부 위젯의 속성(padx 등)을 부모 Frame 안에서 일괄 수정할 수 있기 때문에

코드의 중복과 수정작업을 어느 정도 최소화할 수 있다는 장점도 있습니다.

처음엔 프레임을 사용하는 것이 번거롭고 복잡하게 느껴지시겠지만

GUI의 위젯 수가 많아지고 복잡해지는 시점에서는

프레임 위젯을 도입하여 GUI를 구조화하는 시도를 해 보시기 바랍니다.

 

부록 : 윈도우메모장 페이지 설정창 프레임 따라하기

아래는 윈도우 메모장의 페이지 설정 창의 레이블프레임 위젯을 클론해 보는 작업입니다.

프레임 위치와 사이즈를 최대한 원본에 가깝게 만들어보았습니다. (그 외 위젯을 다 채우지는 않았습니다.)

원본은 아래와 같고,

tkinter로 제작한 화면은 아래와 같습니다.

물론 손코딩한 건 아니고, tkinter의 써드파티 모듈인 pygubu-designer를 이용해 제작해보았습니다.

pygubu-designer 실행화면

 

아래는 위 작업까지 진행한 시점에서 생성한 파이썬 코드입니다.

(가독성을 위해 변수명을 조금 손보고, 리포매팅을 조금 했습니다.)

import tkinter as tk
import tkinter.ttk as ttk

win = tk.Tk()
win.title("페이지 설정")
win.geometry("640x420")
win.resizable(False, False)

labelframe_용지 = ttk.Labelframe(win)
labelframe_용지.configure(height=100, text=' 용지 ', width=100)
labelframe_용지.place(anchor="nw", height=100, relheight=0.0, relwidth=0.0, relx=0.03, rely=0.12, width=400, x=0, y=0)

label1_용지 = ttk.Label(labelframe_용지)
label1_용지.configure(text='크기(Z):   ', underline=3, width=10)
label1_용지.grid(row=0, column=0, padx=20, pady=15)

label2_공급 = ttk.Label(labelframe_용지, state="disabled")
label2_공급.configure(justify="left", takefocus=True, text='공급(S):', underline=3, width=10)
label2_공급.grid(row=1, column=0)

combobox1_용지 = ttk.Combobox(labelframe_용지)
combobox1_용지.configure(state="readonly", validate="focus", values=("A3", "A4", "A5"))
combobox1_용지.grid(row=0, column=1, columnspan=2, ipadx=50)

combobox2_공급 = ttk.Combobox(labelframe_용지, state="disabled")
combobox2_공급.grid(row=1, column=1, columnspan=2, ipadx=50, padx=10, pady=0)

labelframe2_미리보기 = ttk.Labelframe(win)
labelframe2_미리보기.configure(height=200, text=' 미리 보기 ', width=200)
labelframe2_미리보기.place(anchor="nw", height=310, relx=0.67, rely=0.12, width=200, x=0, y=0)

labelframe3_방향 = ttk.Labelframe(win)
labelframe3_방향.configure(height=200, text=' 방향 ', width=200)
labelframe3_방향.place(anchor="nw", height=110, relx=0.03, rely=0.4, width=110, x=0, y=0)

labelframe4_여백 = ttk.Labelframe(win)
labelframe4_여백.configure(height=200, text=' 여백(밀리미터) ', width=200)
labelframe4_여백.place(anchor="nw", height=110, relx=0.22, rely=0.4, width=280, x=0, y=0)

win.mainloop()

부록으로 넣어둔 코드이므로, 설명은 생략하겠습니다.

하지만, 한줄한줄 읽어보시거나, IDE에 붙여넣고 뜯어보시면

어떤 의미인지 가볍게 파악하실 수 있을 거라고 생각합니다.

 

차차 소개해 드리겠지만, 어느 정도 위젯이나 메뉴의 수가 많아지면
이런 위지윅 툴을 사용할 때 
생산성이 엄청 올라가는 시점이 있습니다. (사실 대부분 그렇습니다.)
특히 레이아웃과 위젯들의 배치 등을 꼼꼼하게 조정해야 하는 경우라면
코드 단에서 직접 수정하는 일은 정말 비효율적인 작업이 됩니다.
위의 코드에서도 grid 대신 대부분 place 레이아웃을 사용해서 꼼꼼하게 작업을 했습니다.
그럼에도 시간이 너무 많이 걸려서 완성된 창을 보여드리지 못한 점은 아쉽습니다.

 


다음 포스팅

2022.11.20 - [기타/tkinter 한꼬집씩만 따라해보기] - 23. 프레임 안의 위젯들 속성을 일괄변경하기

 

23. 프레임 안의 위젯들 속성을 일괄변경하기

지난 포스팅 2022.11.20 - [기타/tkinter 한꼬집씩만 따라해보기] - 22. 프레임 위젯 - 위젯들을 묶어주는 위젯 22. 프레임 위젯 - 위젯들을 묶어주는 위젯 지난 포스팅 2022.11.18 - [기타/tkinter 한꼬집씩만

martinii.fun

 

댓글