티스토리 뷰

Python/tkinter

Python,tkinter pack() [공간 다루기]

hwangyoungjae 2016. 6. 16. 09:43
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

pack()메서드에서 사용되는 옵션중 위치 및 공간을 다루는 옵션에대해서 알아보도록 하겠다.

>side = 정렬

>fill = 채우기

>expand = 요구되지 않은공간 사용하기

>anchor = 위치지정

 

>> 공간에 대한 개념 <<

그릇()안에서 창부품의 위치 및 공간을 제어하려면 아래의 3가지 개념을 우선 알고 있어야 한다.

>요구되지 않은 공간(cavity)

>요구되었지만 사용되지 않은 공간

>요구되었고 사용된 공간

아래 표를 어플리케이션에buttonX라는 버튼창부품을 넣을경우 설정된 공간을 간략하게 보여준다.(side=LEFT)

요구되었지만 사용되지 않은 공간

요구되지 않은 공간

(cavity)

요구되었고 사용된 공간(buttonX)

요구되었지만 사용되지 않은 공간

어플리케이션을생성후 버틍창부품을 하나 생성한다면 화면상으로 보여지는 부분은 버튼창부품 하나만 보여질것이다.

하지만실제로 기술적으로 들어가본다면,

side옵션값에 따라서요구된공간과 요구되지 않은 공간으로 나뉘게되고,

요구된공간은 다시사용된공간과 사용되지 않은공간으로 나뉘게 된다.

요구되지 않은공간은 다른창부품을 추가할경우 사용될 공간이라고 생각하면 되고,

요구된 공간은생성한 창부품이 들어갈공간일가고 보면 된다.

 

요구된공간에서사용된 공간은 실제로 창부품이 보여지는 부분으로 보면 된다.

요구된공간에서사용되지 않는 공간은 필요에따라 사용할수도 있고 사용하지 않을수도 있다는 뜻이다.

side옵션을 LEFT로 주게되면 틀에서 왼쪽부분 요구된공간이 된다.

side옵션을 TOP로 주게 되면 틀에서 위쪽부분이 요구된공간이 된다.

 

요구되지 않은공간을 사용하고 싶을경우 expand옵션을 YES로 지정하면된다.

expand옵션을 YES로 지정하면 요구되지 않은 공간을 모두 요구된공간으로사용하게 된다.

창부품이 자신이사용할 공간보다 더 많은 요구된 공간이 생기면 아래와같은 두가지 선택을 하게 된다.

>요구되지 않은 공간으로 이동(anchor옵션 이용)

>요구도지 않은 공간으로 늘리기(fill옵션 이용)

anchor옵션은 동서남북방향에 맞춰서 요구되었지만 사용되지 않은공간에서 위치를 가지게 된다.

fill옵션은 요구되었지만 사용되지 않은공간에 대해서 창부품이 늘어나게 할수 있다.

 

따라서 expand옵션을 NO로 주게 되더라도 anchor옵션과 fill옵션은 사용이 가능하다다만, expand옵션을 주었을때 보여지는 부분이 다르게 보여질수있다.

각 옵션에 대하서좀더 자세히 다루어 보도록 하겠다.

 

-.side(TOP | BOTTOM | LEFT | RIGHT) 기본값=TOP

꾸려질 창부품이틀의 어떤 방향에 정렬이 될것인가를 지정하는 옵션

TOP : 위쪽정렬

BOTTOM : 아래쪽정렬

LEFT : 왼쪽정렬

RIGHT : 오른쪽정렬

각 정렬위치에따라서 요구된공간의 위치도 변형되기 때문에어플리케이션을 디자인할경우 신경써야될 부분이다.

요구된공간을 모두확인하고 싶을경우 fill=BOTH옵션을 사용하게 되면 요구되었지만 사용되지 않은 공간을 확인할수 있다.

아래 예제를 실행하면각 side옵션의 값에 따라서 요구된공간이 어떤식으로 이루어지는지를 보여준다.

# -*- coding:utf-8 -*-
from tkinter import *
class MyApp:
    def __init__(self,parent):
        parent.geometry("300x200")
        self.buttonframe=Frame(parent)
        self.buttonframe.pack(side=LEFT)
        self.button_side=StringVar()
        for item in [TOP,BOTTOM,LEFT,RIGHT]:
            Radiobutton(self.buttonframe,
                        text=str(item),
                        indicator=0,
                        value=item,
                        variable=self.button_side,
                        command=self.update,
                        width=10).pack()
        self.testframe=Frame(parent,background="green")
        self.testframe.pack(side=RIGHT,expand=YES,fill=BOTH)
        self.labelX=Label(self.testframe,text="요구된 공간",background="yellow",width=10,height=1)
        self.labelX.pack()
        self.labelY=Label(self.testframe,text="요구되지 않은 공간",background="green")
        self.labelY.pack(fill=BOTH,expand=YES)
    def update(self):
        self.labelX.pack(side=self.button_side.get(),fill=BOTH)
root=Tk()
myapp=MyApp(root)
root.mainloop()

실행


 

-.expand(YES | NO) 기본값=NO

expand옵션은 요구되지 않은 공간을 모두 요구하고자 할경우 사용하는 옵션이다.

현재 틀에서 요구할수 있는 모든 공간을 요구할수 있게끔 해주는 옵션이다.

보통 fill옵션, anchor옵션과 함께 자주사용되므로아래에서 설명을 다시 하도록 하겠다.

 

-. fill(NONE| X | Y | BOTH) 기본값=NONE

이전 설명에서요구된 공간에는 사용된공간과 사용되지않는 공간이 있다고 했다.

fill옵션은 사용된공간을 사용되지않는공간으로 늘리고자 할때 사용한다.

X = 수평으로만 늘리기

Y = 수직으로만 늘리기

BOTH = 수평,수직 모두 늘리기

NONE = 늘리지 않기

창이 크기가 변형될때프레임의 전체크기가 함께 자동으로 조절되게끔 하려면

expand옵션을 YES로 주고fill옵션을 BOTH로 주면 된다.

 

-.anchor(NW | N | NE | E | SE | S | SW | W | CENTER) | 기본값=CENTER

요구된 공간안에서창부품의 위치를 지정할때 사용된다.

NW = 좌측상단(북서)

N = 중앙상단()

NE = 우측상단(북동)

E = 우측중앙()

SE = 우측하단(남동)

S = 중앙하단()

SW = 좌측하단(남서)

W = 좌측중앙()

CENTER = 정중앙

 9개의 값이 사용되며,

요구된 공간을대상으로 위치선정이 되기때문에, expand옵션을 주지 않은 상태에서는 대각선위치의 경우보여지는 부분에선 별다른 차이점을 못느낄수도 있다.

 

아래예제는 각 옵션에 따른 버튼창부품의 위치가 어떤식으로 지정되고각옵션에 따라 채우기가 어떤식으로 진행되는지를 볼수 있는 예제이다.

코드보단 실행하여 확인하는 어플리케이션이다.

실행했을때의 옵션값은 옵션값을 설정하지 않았을때 지정되는 기본값이다.


# -*- coding:utf-8 -*-
from tkinter import *
 
class MyApp:
    def __init__(self, parent):
        #버튼의 조감을 제어하는데 사용되는 상수들
        button_width=6
        button_padx="2m"
        button_pady="1m"
        button_frame_padx="3m"
        button_frame_pady="2m"
        button_frame_ipadx="3m"
        button_frame_ipady="3m"
       
        #tkinter 변수들, 라디오버튼이 통제하도록 설정
        self.button_name=StringVar()
        self.button_name.set("C")
       
        self.side_option=StringVar()
        self.side_option.set(TOP)
       
        self.fill_option=StringVar()
        self.fill_option.set(NONE)
       
        self.expand_option=StringVar()
        self.expand_option.set(NO)
       
        self.anchor_option=StringVar()
        self.anchor_option.set(CENTER)
       
        #어플리케이션
        self.myParent=parent
        self.myParent.geometry("640x400")
       
        #최상위프레임
        self.myContainer1=Frame(parent)
        self.myContainer1.pack(expand=YES, fill=BOTH)
       
        #제어부분이 들어갈 프레임
        self.control_frame=Frame(self.myContainer1)
        self.control_frame.pack(side=LEFT, expand=NO, padx=10, pady=5, ipadx=5, ipady=5)
       
        #제어프레임에 들어갈 설명
        myMessage="This window shows the effects of the \nexpand, fill, and anchor packing option. \n"
        Label(self.control_frame, text=myMessage, justify=LEFT).pack(side=TOP, anchor=W)
       
        #제어버튼이 들어갈 프레임
        self.buttons_frame=Frame(self.control_frame)
        self.buttons_frame.pack(side=TOP, expand=NO, fill=Y, ipadx=5, ipady=5)
       
        #테스트결과를 볼프레임들을 넣을 메인프레임
        self.demo_frame=Frame(self.myContainer1)
        self.demo_frame.pack(side=RIGHT, expand=YES, fill=BOTH)
       
        #테스트결과 B,C가 들어갈 프레임
        self.top_frame=Frame(self.demo_frame)
        self.top_frame.pack(side=TOP, expand=YES, fill=BOTH)
        
        #테스트결과 A가 들어갈 프레임
        self.bottom_frame=Frame(self.demo_frame, borderwidth=5,
                                relief=RIDGE, height=50, bg="cyan")
        self.bottom_frame.pack(side=TOP, fill=X)
       
        #테스트결과 B가 들어갈 프레임
        self.left_frame=Frame(self.top_frame, background="red",
                              borderwidth=5, relief=RIDGE, width=50)
        self.left_frame.pack(side=LEFT, expand=NO, fill=Y)
       
        #테스트결과 C가 들어갈 프레임
        self.right_frame=Frame(self.top_frame, background="tan",
                               borderwidth=5, relief=RIDGE, width=250)
        self.right_frame.pack(side=RIGHT, expand=YES, fill=BOTH)
       
        #각 테스트프레임에 버튼생성
        button_names=["A", "B", "C"]
        side_options=[LEFT, TOP, RIGHT, BOTTOM]
        fill_options=[X, Y, BOTH, NONE]
        expand_options=[YES, NO]
        anchor_options=[NW, N, NE, E, SE, S, SW, W, CENTER]
       
        self.buttonA=Button(self.bottom_frame, text="A")
        self.buttonA.pack()
        self.buttonB=Button(self.left_frame,text="B")
        self.buttonB.pack()
        self.buttonC=Button(self.right_frame, text="C")
        self.buttonC.pack()
        self.button_with_name={"A":self.buttonA, "B":self.buttonB, "C":self.buttonC}
       
        #제어용 프레임에 종류별프레임과 버튼 생성
        self.button_names_frame=Frame(self.buttons_frame, borderwidth=5)
        self.side_options_frame=Frame(self.buttons_frame, borderwidth=5)
        self.fill_options_frame=Frame(self.buttons_frame, borderwidth=5)
        self.expand_options_frame=Frame(self.buttons_frame, borderwidth=5)
        self.anchor_options_frame=Frame(self.buttons_frame, borderwidth=5)
       
        self.button_names_frame.pack(side=LEFT, expand=YES, fill=Y, anchor=N)
        self.side_options_frame.pack(side=LEFT, expand=YES, anchor=N)
        self.fill_options_frame.pack(side=LEFT, expand=YES, anchor=N)
        self.expand_options_frame.pack(side=LEFT, expand=YES, anchor=N)
        self.anchor_options_frame.pack(side=LEFT, expand=YES, anchor=N)
       
        Label(self.button_names_frame, text="\nButton").pack()
        Label(self.side_options_frame, text="Side\nOption").pack()
        Label(self.fill_options_frame, text="Fill\nOption").pack()
        Label(self.expand_options_frame, text="Expand\nOption").pack()
        Label(self.anchor_options_frame, text="Anchor\nOption").pack()
       
        for option in button_names:
            button=Radiobutton(self.button_names_frame,
                               text=str(option),
                               indicatoron=1,
                               value=option,
                               command=self.button_refresh,
                               variable=self.button_name)
            button["width"]=button_width
            button.pack(side=TOP)
       
        for option in side_options:
            button=Radiobutton(self.side_options_frame,
                               text=str(option),
                               indicatoron=0,
                               value=option,
                               command=self.demo_update,
                               variable=self.side_option)
            button["width"]=button_width
            button.pack(side=TOP)
           
        for option in fill_options:
            button=Radiobutton(self.fill_options_frame,
                               text=str(option),
                               indicatoron=0,
                               value=option,
                               command=self.demo_update,
                               variable=self.fill_option)
            button["width"]=button_width
            button.pack(side=TOP)
       
        for option in expand_options:
            button=Radiobutton(self.expand_options_frame,
                               text=str(option),
                               indicatoron=0,
                               value=option,
                               command=self.demo_update,
                               variable=self.expand_option)
            button["width"]=button_width
            button.pack(side=TOP)
           
        for option in anchor_options:
            button=Radiobutton(self.anchor_options_frame,
                               text=str(option),
                               indicatoron=0,
                               value=option,
                               command=self.demo_update,
                               variable=self.anchor_option)
            button["width"]=button_width
            button.pack(side=TOP)
       
        #Calncel버튼생성
        self.cancelButtonFrame=Frame(self.button_names_frame)
        self.cancelButtonFrame.pack(side=BOTTOM, expand=YES, anchor=SW)
       
        self.cancelButton=Button(self.cancelButtonFrame, text="Cancel",
                                 background="red", width=button_width,
                                 padx=button_padx, pady=button_pady)
        self.cancelButton.pack(side=BOTTOM, anchor=S)
       
        self.cancelButton.bind("<Button-1>", self.cancelButtonClick)
        self.cancelButton.bind("<Return>", self.cancelButtonClick)
       
        #테스트 초기 실행
        self.demo_update()
   
    def button_refresh(self):
        button=self.button_with_name[self.button_name.get()]
        properties=button.pack_info()
        self.fill_option.set(properties["fill"])
        self.side_option.set(properties["side"])
        self.expand_option.set(properties["expand"])
        self.anchor_option.set(properties["anchor"])
   
    def demo_update(self):
        button=self.button_with_name[self.button_name.get()]
        button.pack(fill=self.fill_option.get(),
                    side=self.side_option.get(),
                    expand=self.expand_option.get(),
                    anchor=self.anchor_option.get())
       
    def cancelButtonClick(self, event):
        self.myParent.destroy()
       
root=Tk()
myapp=MyApp(root)
root.mainloop()




 

참조 : http://coreapython.hosting.paran.com/GUI/Thinking%20in%20Tkinter.htm

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함