grid — 위젯을 격자로 배열하는 지오메트리 매니저

grid — 위젯을 격자로 배열하는 지오메트리 매니저

위젯들을 행과 열로 정확히 배치하고 싶을 때, 좌표를 하나하나 계산하는 건 번거로워요. Tk의 grid 명령은 다른 창(지오메트리 컨테이너, 또는 컨테이너 창) 안에서 위젯을 행과 열로 배열하는 grid 지오메트리 매니저와 통신하는 데 사용됩니다. 표 같은 레이아웃을 만드는 데 가장 자연스러운 도구예요.

출처: grid (Tcl/Tk 8.6.18 매뉴얼)

본문

개요

grid option arg ?arg ...?

grid 명령은 option 인자에 따라 여러 형태를 가질 수 있습니다.

명령 형태

grid window ?window ...? ?options? — 첫 인자가 grid configure의 첫 창 인자로 적합한 경우(창 이름, 즉 .로 시작하는 값 또는 아래 "상대 배치" 섹션의 x^ 문자), grid configure와 같은 방식으로 처리됩니다.

grid anchor window ?anchor? — 어떤 행/열에도 weight가 없을 때 컨테이너 창 안에 grid를 어떻게 배치할지 anchor 값이 제어합니다. 기본 anchornw예요.

grid bbox window ?column row? ?column2 row2? — 인자 없이 호출하면 grid의 경계 상자(픽셀 단위)를 돌려줍니다. 반환 값은 정수 4개로, 처음 두 개는 컨테이너 창에서 grid의 왼쪽 위 모서리까지의 픽셀 오프셋(x, y)이고, 다음 두 개는 grid의 너비와 높이(픽셀)입니다. columnrow를 하나씩 지정하면 그 셀의 경계 상자를 돌려주는데, 왼쪽 위 셀이 0부터 번호가 매겨져요. columnrow 인자를 둘 다 지정하면 표시된 행과 열을 가로지르는 경계 상자를 돌려줍니다.

grid columnconfigure window index ?-option value ...? — 지오메트리 컨테이너 windowindex 열의 열 속성을 조회하거나 설정합니다. 유효한 옵션은 -minsize, -weight, -uniform, -pad입니다. 옵션이 하나 이상 제공되면 index를 열 인덱스 리스트로 줄 수 있으며 설정 옵션이 그 열들에 적용돼요. 인덱스는 정수, 창 이름, 또는 키워드 all일 수 있어요. all이면 옵션이 현재 컨텐츠 창이 차지한 모든 열에 적용됩니다. 창 이름이면 그 창은 이 컨테이너의 컨텐츠여야 하고 옵션이 그 컨텐츠가 차지한 모든 열에 적용돼요.

-minsize 옵션은 이 열에 허용될 최소 크기를 화면 단위로 설정합니다. -weight 옵션(정수 값)은 열들 사이에 여분 공간을 배분하는 상대 가중치를 설정해요. weight가 0이면 열이 요청된 크기에서 벗어나지 않음을 나타냅니다. weight가 2인 열은 레이아웃에 여분 공간이 할당될 때 weight 1인 열의 두 배 속도로 커져요. -uniform 옵션은 비어 있지 않은 값을 주면 그 열을 같은 -uniform 값을 가진 다른 열들과 uniform group으로 묶습니다. uniform group에 속한 열의 공간은 항상 -weight 값에 엄격히 비례하도록 할당돼요. -pad 옵션은 grid 지오메트리 매니저가 포함 창에서 크기를 요청할 때 그 열에 완전히 포함된 가장 큰 창에 더해질 화면 단위 수를 지정합니다.

옵션만 지정하고 값이 없으면 그 옵션의 현재 값을 돌려줍니다. 컨테이너 창과 인덱스만 지정하면 현재 설정을 모두 "-option value" 쌍 리스트로 돌려줍니다.

grid configure window ?window ...? ?options? — 인자는 하나 이상의 컨텐츠 창 이름 뒤에 관리 방법을 지정하는 인자 쌍으로 이뤄져요. window 이름 대신 -, x, ^ 문자를 지정해 window의 기본 위치를 바꿀 수 있습니다(아래 "상대 배치" 섹션 참조). 지원되는 옵션은 다음과 같아요.

-column n — 창이 grid에서 n번째 열을 차지하도록 삽입합니다. 열 번호는 0부터 시작해요. 이 옵션을 제공하지 않으면 이 grid 호출에서 이전에 지정한 창의 바로 오른쪽에 창이 배치되고, 첫 창이면 열 "0"에 배치됩니다. window 바로 앞에 오는 각 x에 대해 열 위치가 1씩 증가해요. 즉 x는 이 행에서 grid의 빈 열을 나타냅니다.

-columnspan n — 창이 grid에서 n개 열을 차지하도록 삽입합니다. 기본은 한 열이지만, 창 이름 뒤에 -가 오면 각각의 바로 뒤 -마다 columnspan이 1씩 증가해요.

-in container — 창(들)을 container로 주어진 컨테이너 창 안에 삽입합니다. 기본은 첫 창의 부모 창이에요.

-ipadx amount — 컨텐츠 양쪽에 남길 수평 내부 패딩의 양을 지정합니다. 이 공간은 컨텐츠 테두리 안쪽에 더해져요. amount2.5c 같은 유효한 화면 거리여야 합니다. 기본값은 0이에요.

-ipady amount — 컨텐츠 위아래에 남길 수직 내부 패딩의 양을 지정합니다. 컨텐츠 테두리 안쪽에 더해져요. 기본값은 0입니다.

-padx amount — 컨텐츠 양쪽에 남길 수평 외부 패딩의 양을 화면 단위로 지정합니다. amount는 왼쪽·오른쪽을 각각 지정하는 두 값의 리스트일 수 있어요. 기본값은 0이에요. 이 공간은 컨텐츠 테두리 바깥쪽에 더해집니다.

-pady amount — 컨텐츠 위아래에 남길 수직 외부 패딩의 양을 화면 단위로 지정합니다. amount는 위쪽·아래쪽을 각각 지정하는 두 값의 리스트일 수 있어요. 기본값은 0이고, 컨텐츠 테두리 바깥쪽에 더해집니다.

-row n — 컨텐츠가 grid에서 n번째 행을 차지하도록 삽입합니다. 행 번호는 0부터 시작해요. 이 옵션을 제공하지 않으면 이 grid 호출에서 이전에 지정한 컨텐츠와 같은 행에 배치되고, 첫 컨텐츠면 가장 높은 점유 행의 다음 행에 배치됩니다.

-rowspan n — 컨텐츠가 grid에서 n개 행을 차지하도록 삽입합니다. 기본은 한 행이에요. 다음 grid 명령에 이 content의 열과 정렬되는 ^ 문자가 content 대신 들어오면 이 content의 rowspan이 1만큼 확장됩니다.

-sticky style — 컨텐츠의 셀이 요청된 치수보다 크면, 이 옵션으로 셀 안에서 컨텐츠를 위치시키거나 늘릴 수 있어요. stylen, s, e, w 문자 중 0개 이상을 포함하는 문자열입니다. 선택적으로 공백이나 쉼표를 포함할 수 있지만 무시돼요. 각 문자는 컨텐츠가 "붙을" 면(북·남·동·서)을 가리킵니다. ns(또는 ew)를 둘 다 지정하면 컨텐츠가 캐비티의 전체 높이(또는 너비)를 채우도록 늘어나요. -sticky 옵션은 pack이 쓰는 -anchor-fill의 조합을 대신합니다. 기본은 ""이며, 컨텐츠가 요청된 크기로 캐비티 중앙에 배치됩니다.

컨텐츠가 이미 지오메트리 매니저에 의해 관리되고 있다면, 지정되지 않은 옵션은 기본값을 받는 대신 이전 값을 유지합니다.

grid forget window ?window ...? — 각 window를 자기 컨테이너의 grid에서 제거하고 그 창들을 언매핑합니다. 컨텐츠는 더 이상 grid 지오메트리 매니저에 관리되지 않아요. 그 창의 설정 옵션은 잊혀져서, 창이 다시 grid 지오메트리 매니저에 관리되면 초기 기본 설정이 사용됩니다.

grid info windowwindow로 주어진 컨텐츠의 현재 설정 상태를 grid configure에 지정할 수 있는 것과 같은 옵션-값 형태로 나타낸 리스트를 돌려줍니다. 리스트의 처음 두 요소는 "-in container"로, 여기서 container는 창의 컨테이너 창이에요.

grid location window x y — 컨테이너 창 기준 화면 단위의 x, y 값이 주어지면, 그 위치의 열과 행 번호를 돌려줍니다. grid의 위쪽이나 왼쪽에 있는 위치에는 -1을 돌려줘요.

grid propagate window ?boolean?boolean1이나 on 같은 참 불리언 값이면 window에 대해 전파(propagation)가 켜집니다. window는 창 이름이어야 해요. 거짓 불리언 값이면 전파가 꺼집니다. 두 경우 모두 빈 문자열을 돌려줘요. boolean을 생략하면 명령은 window에 전파가 현재 켜져 있는지 0 또는 1로 돌려줍니다. 전파는 기본적으로 켜져 있어요.

grid rowconfigure window index ?-option value ...? — 지오메트리 창 windowindex 행의 행 속성을 조회하거나 설정합니다. 옵션과 동작은 columnconfigure와 동일하게 -minsize, -weight, -uniform, -pad를 지원합니다.

grid remove window ?window ...? — 각 window를 자기 컨테이너의 grid에서 제거하고 언매핑합니다. grid forget과 달리 그 창의 설정 옵션은 기억돼서, 컨텐츠 창이 다시 관리되면 이전 값이 유지돼요.

grid size containercontainer의 grid 크기(열 다음 행)를 돌려줍니다. 크기는 가장 큰 행이나 열을 차지하는 content, 또는 0이 아닌 -minsize, -weight, -pad를 가진 가장 큰 열이나 행으로 결정됩니다.

grid slaves window ?-option value? — 옵션 없이 호출하면 window의 모든 컨텐츠 리스트를 가장 최근에 관리된 것부터 돌려줍니다. option-row-column일 수 있으며, 그 경우 value가 지정한 행(또는 열)의 컨텐츠만 돌려줍니다.

grid content window ?-option value?grid slaves window ?-option value?의 동의어입니다.

상대 배치

grid 명령은 각 컨텐츠의 행·열 정보를 일일이 지정하지 않고도 레이아웃을 만들 수 있는 제한된 능력을 갖고 있어요. 덕분에 행·열 정보를 명시하지 않고도 컨텐츠를 재배치하거나 추가·제거할 수 있습니다.

컨텐츠에 열이나 행 정보를 지정하지 않으면, 관리될 때 -column, -row, -columnspan, -rowspan의 기본값이 선택됩니다. 값은 grid의 현재 레이아웃, 같은 grid 명령에서 다른 컨텐츠에 대한 상대 위치, 그리고 컨텐츠 이름이 일반적으로 예상되는 자리의 -, x, ^ 문자의 유무에 따라 정해져요.

- — 왼쪽 컨텐츠의 -columnspan을 1 증가시킵니다. 연속된 여러 -는 덮는 열 수를 차례로 늘려요. -^이나 x 뒤에 올 수 없고, grid configure의 첫 content 인자가 될 수도 없습니다.

x — 왼쪽 컨텐츠와 오른쪽 컨텐츠 사이에 빈 열을 남깁니다.

^ — grid에서 위쪽 컨텐츠의 -rowspan을 확장합니다. 한 행의 ^ 개수는 위쪽 컨텐츠가 덮는 열 수와 일치해야 해요.

grid 알고리즘

grid 지오메트리 매니저는 세 단계로 컨텐츠를 배치합니다. 첫 단계에서 모든 컨텐츠를 맞추는 데 필요한 최소 크기를 계산하고(전파가 켜져 있으면) 컨테이너 창에 그 크기가 되도록 요청합니다. 두 번째 단계에서 요청된 크기를 컨테이너의 실제 크기와 비교합니다. 크기가 다르면 레이아웃에 필요한 대로 공간을 더하거나 뺍니다. 마지막 단계에서 각 컨텐츠는 sticky 플래그 설정에 따라 자신의 행과 열에 배치됩니다.

레이아웃의 최소 크기를 계산하려면 먼저 -columnspan-rowspan 값이 1인 모든 컨텐츠를 보는데, 각 행·열의 명목 크기는 그 행·열의 minsize 또는 padding에 가장 큰 컨텐츠의 크기를 더한 값 중 큰 쪽으로 정합니다. 그다음 각 uniform group의 행·열이 서로 맞춰집니다. 그다음 rowspan이나 columnspan이 1보다 큰 컨텐츠를 살펴봐요. 이 컨텐츠를 수용하려면 행·열 그룹의 크기를 늘려야 한다면, 그룹의 각 행·열에 weight에 따라 여분 공간을 더합니다. 모든 weight가 0인 각 그룹에서는 여분 공간이 균등하게 배분됩니다.

여러 행·열이 uniform group에 속하면 할당되는 공간은 항상 weight에 비례합니다(weight 0은 1로 간주). 즉 -weight 1 -uniform a로 설정한 행·열은 같은 값의 다른 행·열과 정확히 같은 크기를 가집니다. -weight 2 -uniform b로 설정한 행·열은 -weight 1 -uniform b로 설정한 것의 정확히 두 배 크기가 돼요.

더 기술적으로, 그룹의 각 행·열은 어떤 상수 k에 대해 k*weight와 같은 크기가 됩니다. 상수 k는 어떤 행·열도 최소 크기보다 작아지지 않도록 고릅니다. 예를 들어 그룹의 모든 행·열이 같은 weight를 가지면 각 행·열은 그룹에서 가장 큰 행·열과 같은 크기를 가져요.

컨테이너 크기가 요청된 레이아웃보다 크면 여분 공간이 행·열 weight에 따라 배분됩니다. 모든 weight가 0이면 레이아웃이 anchor 값에 따라 컨테이너 안에 배치돼요. 컨테이너 크기가 요청된 레이아웃보다 작으면 행·열에서 weight에 따라 공간이 제거됩니다. 다만 행·열이 minsize로 줄어들면 그 weight는 0으로 간주됩니다. 모든 행·열이 최소 크기에 있는 것처럼 레이아웃에서 제거할 공간이 허용치보다 더 많으면, 레이아웃은 anchor 값에 따라 배치되고 잘립니다.

지오메트리 전파

grid 지오메트리 매니저는 보통 컨테이너가 자신의 컨텐츠 요구를 정확히 충족하려면 얼마나 커야 하는지 계산하고, 컨테이너의 요청된 너비와 높이를 그 치수로 설정합니다. 이렇게 하면 지오메트리 정보가 창 계층을 따라 toplevel 창까지 전파되어, 전체 하위 트리가 잎(leaf) 창의 요구에 맞춰 크기를 조정해요.

하지만 grid propagate 명령으로 하나 이상의 컨테이너에 대해 전파를 끌 수 있습니다. 전파가 꺼지면 grid가 컨테이너 창의 요청된 너비와 높이를 설정하지 않아요. 예를 들어 컨테이너 창을 당신이 지정한 고정 크기로 만들고 싶을 때 유용합니다.

컨테이너 창 제한

각 컨텐츠의 컨테이너는 컨텐츠의 부모(기본값)이거나 부모의 자손이어야 해요. 이 제한은 컨텐츠가 부모에 잘리지 않고 컨테이너의 보이는 어떤 부분 위에도 놓일 수 있도록 보장하기 위해 필요합니다. 또한 한 grid 호출의 모든 컨텐츠는 같은 컨테이너를 가져야 해요.

쌓임 순서

컨텐츠의 컨테이너가 그 부모가 아니라면, 컨텐츠가 컨테이너보다 쌓임 순서에서 더 위에 있도록 해야 해요. 그렇지 않으면 컨테이너가 컨테이너 내용을 가려서, 컨텐츠가 제대로 관리되지 않은 것처럼 보일 수 있어요. 컨텐츠가 컨테이너보다 위에 있게 하는 가장 쉬운 방법은 컨테이너 창을 먼저 만드는 것입니다. 가장 최근에 만든 창이 쌓임 순서에서 가장 위에 있으니까요.

크레딧

grid 명령은 Doug Stein이 쓴 GridBag 지오메트리 매니저와 George Howlett이 쓴 blt_table 지오메트리 매니저에서 아이디어를 얻었습니다.

예제

텍스트 위젯과 스크롤바 두 개를 포함하는 toplevel 창:

# 위젯 만들기
toplevel .t
text .t.txt -wrap none -xscroll {.t.h set} -yscroll {.t.v set}
scrollbar .t.v -orient vertical   -command {.t.txt yview}
scrollbar .t.h -orient horizontal -command {.t.txt xview}

# 배치하기
grid .t.txt .t.v -sticky nsew
grid .t.h        -sticky nsew

# 트텍스트 위젯이 여분 공간을 다 차지하게
grid rowconfigure    .t .t.txt -weight 1
grid columnconfigure .t .t.txt -weight 1

서로 다른 "자연" 너비에도 불구하고 같은 너비를 가진 위젯 세 개:

button .b -text "Foo"
entry .e -textvariable foo ; set foo "Hello World!"
label .l -text "This is a fairly long piece of text"

grid .b .e .l -sticky ew
grid columnconfigure . "all" -uniform allTheSame

더 알아보기

  • pack — 상자형 지오메트리 매니저
  • place — 절대 좌표 지오메트리 매니저