본문 바로가기
Python/Python tkinter

[Python tkinter] 3. Frame 위젯으로 창 구획 나누기

by Rosmary 2022. 1. 16.
728x90
반응형

 

 

 

GUI로 프로그램을 만들 때, 필자가 가장 중요하게 생각하는 것은 디자인이다. 굉장히 뜬금없이 들릴 수 있는데, 외관을 삐까번쩍하게 만드는 그런 디자인을 말하는 것이 아니라, 위젯을 적절한 위치에 배치할 수 있도록 공간을 할당하는 것을 의미한다. 가령 예시를 하나 보자. 로그인 창을 만든다고 하자.

 

 

"아이디", "비밀번호" 텍스트가 작성된 Label 위젯과 로그인 폼을 입력받는 Entry 위젯은 전부 place로 창에 배치가 되었다. 만약, 개발을 진행하다가 누군가가 "이거 위젯 위치 오른쪽으로 40 픽셀정도 옮겨주세요"라는 부탁을 받는다면, 필자는 place 함수에 있는 x인자의 값을 전부 하나씩 변경해주어야 한다. 위의 예시야 위젯 개수가 단 4개 뿐이니 그냥 노가다라도 하면 된다지만, 코드가 늘어나서 위젯을 배치한 코드가 어디에 묻혀있는지 찾기 어려운데다 위젯 수까지 늘어난다면 이 작업을 수행하기가 여간 까다로워지는 것이 아니다. 

 

 그럼, 이렇게 하면 어떨까? 특정 위젯이 배치될 공간을 미리 나누고, 위젯을 각각의 나누어진 공간에 할당해주는 것이다. 이렇게 할 경우, 누군가가 "위젯들의 위치를 옮겨주세요!" 라고 요구하더라도, 나누어진 공간들의 위치만 조정해주면 되기 때문에 훨씬 관리가 쉬워진다.

 

창 내의 구역을 나누는데 사용하는 tkinter의 위젯은 Frame이다. 이번 포스팅에서는 창 내 위젯을 예쁘게 배치하기 위해 Frame을 이용해 공간을 나누는 과정에 대해 알아보려 한다.

 

본 포스팅을 참고하기 전에 위젯의 생성과 배치 과정에 대한 내용을 참조하실 분은 여기를 참고하시면 된다.

 

 

 

1. Frame 위젯 호출

 

필자는 방금 만든 로그인 창을 아래와 같이 구획을 나누어보려 한다.

 

파란색 Frame은 글자가 입력될 Label 위젯을 배치하는 공간으로, 빨간 Frame은 값을 입력받는  Entry 위젯을 배치하는 공간으로 나누어보려 한다.

 

Frame 위젯은 tkinter 패키지 내에 class 형태로 코드가 짜여 있으므로, 아래와 같이 호출해주면 된다.

 

tkinter.Frame(Frame 인자들)

 

(1) Frame() 클래스 인자

 

Frame() 클래스는 호출 시, 보통 아래의 인자를 사용한다.

 

< Frame 위젯 사이즈 관련>

-  width: Frame 위젯의 가로 크기(PIxel) 입력(int형 값 입력)

-  height: Frame 위젯의 세로 크기(PIxel) 입력(int형 값 입력)

-  padx : Frame 위젯의 가로 패딩 크기(Pixel)입력(int 형 값 입력)

-  pady : Frame 위젯의 세로 패딩 크기(Pixel)입력(int 형 값 입력)

 

< Frame 위젯 모양 관련>

-  relief : Frame의 테두리 모양 설정. 

     * 설정값:  "flat"(기본값), "solid", "raised", "sunken", "ridge" 

-  bd 또는 borderwidth: 테두리 두께(int형 값 입력)

-  bg 또는 background: 배경 색 지정("red", "green", "blue" 등 색 지정)

 

 

Frame은 단순히 구획을 나누는 용도로 사용하다보니 다른 위젯에 비해 인자가 많은 편은 아니다(또한 다른 위젯에서 사용하는 공통 인자가 대부분이다). 본격적으로 Frame 2개를 만들어보자. 

 

Frame 생성 코드에서 tkinter.Frame(window, width=100....) 으로 작성하는 것이 정석이다. 배치할 창을 실수로 빼먹었다.

 

tkinter.Frame()으로 Frame 위젯 생성 후, place() 등으로 위젯을 창에 배치하면 위와 같이 Frame이 지정한 위치에 생성되는 것을 확인할 수 있다. 필자가 시각정보 활용을 위해 relief와 bg값을 설정하였는데, relief와 bd를 별도로 지정하지 않으면, 창에는 아무 표시가 되지 않는다. 따라서 의도한 디자인이 아닌 경우, relief와 bd 인자를 Frame 위젯 생성 시 최종적으로 지정하는 일은 매우 드물다. 대신 개발 과정에서 섬세하게 공간을 나누어야 하는 작업이 필요한 경우, 시각적인 도움을 얻기 위해 활용하는 경우가 매우 많다.

 

사실상, Frame 위젯의 생성과 배치는 이게 끝이다. 이제 이 Frame에 다른 위젯들을 배치해보려 한다. 

 

 

(2) Frame에 위젯 배치

 

추후 작성할 포스팅에서도 지겹게 시연할 내용이지만, 위젯을 창에 나타내기 위해서는, 위의 스크린샷에서 생성 코드와 배치 코드가 나누어 진 것을 보면 알 수 있듯이 위젯의 생성과 위젯의 배치와 관련된 코드를 작성해야 한다. 

이제 필자는 "아이디"와 "비밀번호" 텍스트를 Label 위젯으로 만들어 빨간 Frame에, 폼을 입력받는 Entry 위젯은 파란 Frame에 위치시키려한다.

 

 

위젯의 Frame 내 배치는 크게 어렵지 않다. 위젯 생성 시, 배치할 위치(master) 인자를 frame 객체 명으로 지정해주면 된다. 필자의 경우, pack()으로 Label과 Entry 위젯을 배치했는데, 이 때문에 Frame의 크기가 내부 위젯 크기에 자동 맞춤이 되어 버렸다. place() 함수를 사용하는 경우, Frame의 크기는 생성 시 지정한 인자에 맞게 유지된다.

 

 

단, place 함수를 사용하여 Frame 내에 위젯을 배치할 때, 위젯의 가로, 세로축 위치는 위젯이 배치될 Frame을 기준으로 한다. entry_id의 경우, x=0, y=0으로 지정되어 있음에도 창의 좌상단이 아닌 frame2의 좌상단에 위치하고 있음을 확인해보자. 

 

Frame으로 구성한 창에서 "오른쪽으로 몇 PX 옮겨주세요" 와 같은 수정사항이 생기면 단순히 Frame 위젯의 위치만 변경해주면 된다. 코드의 수정과 유지가 더욱 간편해진다.

 

Frame과 관련된 내용은 이게 끝이다. 매우 쉽다.

 

유사한 위젯으로 LabelFrame이라는 녀석도 있는데, 이 녀석은 나누어진 구역의 테두리 상단에 구획의 이름을 지정할 수 있다. 인자는 text="구획 이름"을 추가해주면 된다. 예시는 아래와 같다.

 

 

 

 


 

이번 포스팅에서는 tkinter의 창 내 구획을 Frame 위젯으로 나누고, Frame 내에 다른 위젯을 배치하는 방법에 대해 알아보았다. 늘 그랬듯이 테스트 코드는 아래에 첨부한다.

 

003_tkinter_Frame.py
0.00MB

 

 

다음 포스팅에서는 창 내에 글자를 각인하는 Label 위젯에 대해서 알아보려 한다. 

 

 

 

Fin.

반응형

댓글