본문으로 바로가기

GUI 툴킷 패키지 Tix #1

category 카테고리 없음 2024. 6. 26. 13:58

오랜만의 글이군요. 이번글은 조금 길어질 듯합니다.

 

홈페이지: http://tix.sourceforge.net

Tix란?

Tix (Tk Interface eXtension)는 Tcl/Tk와 Python/Tkinter 라이브러리에 사용 가능한 Tk보다 진보된 복잡한 위젯을 제공하는 GUI 툴킷 라이브러리입니다. Tix는 Ioi K. Lam에 의해 1993년에 개발이 시작된 전통성 있는 오픈소스이며, BSD 라이선스를 따릅니다. 즉 재배포가 가능합니다. Tix의 최신 버전은 8.4.3이며, Tcl/Tk 8.0 이상에서 동작합니다.

Tix의 주요 중요 기능

  • 계층구조 리스트 위젯
  • 그리드 위젯 (워크시트, 편집도 가능)
  • 콤보 위젯과 옵션 메뉴
  • 노트북 위젯
  • 표준 Tk위젯보다 강력한 리스트 위젯
  • 표준 Tk위젯보다 강력한 파일 선택 대화상자
  • 디렉토리 선택 대화상자
  • 진행바 위젯
  • XPM 이미지 지원
  • ...

그리드 (tixGrid) 1

Tix의 Grid는 Tk의 Grid와 무관합니다. ^_^ tixGrid는 격자 모양으로 구분된 셀에 문자, 이미지 및 위젯등을 입력할 수 있는 워크시트 모양의 위젯입니다.

package require Tix
wm title . "품목"
proc CBFormat {w area x1 y1 x2 y2} {
        case $area {
                main {
                        $w format grid $x1 $y1 $x2 $y2 \
                                -bd 1 -bordercolor #606060 -relief raised \
                                -bg #c0c0c0 -fill 1
                }
                x-margin {
                        $w format grid $x1 $y1 $x2 $y2 \
                                -bd 1 -bordercolor #606060 -relief raised \
                                -bg #f0c0c0 -fill 1
                }
                y-margin {
                        $w format grid $x1 $y1 $x2 $y2 \
                                -bd 1 -bordercolor #606060 -relief raised \
                                -bg #c0c0f0 -fill 1
                }
                s-margin {
                        $w format grid $x1 $y1 $x2 $y2 \
                                -bd 1 -bordercolor #606060 -relief raised \
                                -bg #f0f0f0 -fill 1
                }
        }
}

set f [frame .f]
set g [tixGrid $f.g -width 8 -height 6 \
        -format "CBFormat $f.g" \
        -xscrollcommand "$f.scrh set" \
        -yscrollcommand "$f.scrv set"]
set scrv [scrollbar $f.scrv -ori v -com "$g yview"]
set scrh [scrollbar $f.scrh -ori h -com "$g xview"]
grid $g -row 0 -column 0
grid $scrv -row 0 -column 1 -sticky ns
grid $scrh -row 1 -column 0 -sticky ew

$g size col 0 -size 16char
$g set 0 0 -itemtype text -text 품목
set RowTitles [list 고등어 삼겹살 햄버거 생선 튀김 고추 계란 냉면]

set y 1
foreach e $RowTitles {
        $g set 0 $y -itemtype text -text $e
        incr y
}

set ColTitles {10 11 12 13 14 15 16 17 18}
set x 1
foreach e $ColTitles {
        $g size col $x -size 4char
        $g set $x 0 -itemtype text -text $e
        incr x
}

set data {
  {2 * * 2 * * 2 * *}
  {1 3 * 2 * 1 3 * 2}
  {1 * 4 * 1 3 * 2 1}
  {* * * 2 * * * 3 *}
  {1 * 1 * * * 1 * *}
  {* 3 * * * 3 * * 2}
  {* * 2 2 * * 2 2 *}
  {* 1 1 * * 1 1 * 1}
}
set y 1
foreach e $data {
        set x 1
        foreach d $e {
                $g set $x $y -itemtype text -text $d
                incr x
        }
        incr y
}
ttk::button .b -text "Exit" -command exit
pack $f .b -side top -anchor e
# end.

 

그리드는 tixGrid 커맨드로 생성합니다. tixScrolledGrid는 스크롤 기능을 갖춘 그리드이지만, 일단 tixGrid에 대해서만 알아봅니다. tixGrid는 스크롤 기능이 없기 때문에, Tk의 스크롤 막대를 수동으로 붙여야만 합니다.

set g [tixGrid $f.g -width 8 -height 6 \
        -format "CBFormat $f.g" \
        -xscrollcommand "$f.scrh set" \
        -yscrollcommand "$f.scrv set"]

 

-width와 -height 옵션으로 최대 셀의 크기를 지정합니다. 각 셀 색상과 글꼴을 지정하려면, - formatcmd (- format) 옵션에 콜백 프로시져를 지정합니다. 이것은 셀을 다시 그리기가 필요할 때 자동으로 불리는 함수이며, 뒤에 5개의 인자가 따라옵니다.

proc CBFormat {w area x1 y1 x2 y2} {
        case $area {
                main {
                        $w format grid $x1 $y1 $x2 $y2 \
                                -bd 1 -bordercolor #606060 -relief raised \
                                -bg #c0c0c0 -fill 1
                }
...

 

(x1, y1) - (x2, y2) 셀 범위에서 area는 다음과 같이 정의됩니다.

  • x> 0 and y> 0 일 때: main
  • x = 0 and y = 0 때: s-margin
  • x = 0 and y> 0 일 때: y-margin
  • x> 0 and y = 0 때: x-margin

format 하위 커맨드는 format grid와 format border 커맨드가 있습니다. format grid는 셀 내부를, format border는 셀 테두리 그리기 형식 지정에 사용됩니다. 옵션 매뉴얼을 보면 알 수 있으므로, 생략합니다. 여기서는 왼쪽 상단의 셀 (area가 s-margin)인 경우 흰색, (x-margin)인 경우 적색, (y-margin)인 경우 파란색으로, 그렇지 않은 경우 어두운 느낌의 그레이를 지정합니다. 다음은 행 높이와 열 너비지만, 기본으로 auto (최소의 크기를 자동 감지)이며, size 하위 커맨드를 사용합니다.

$g size col 0 -size 16char

-size 단위는 픽셀이며, 문자 지정 시 6char 같이 "char"를 지정합니다. 이 값이 기본 "auto"값이 됩니다. 그리고 셀에 데이터를 넣습니다. 이것은 set 하위 명령에 행, 열 순서로 위치를 지정하며, 인덱스는 0부터 시작합니다.

$g set 0 0 -itemtype text -text 품목

-itemtype은 text 외에 image, imagetext, window가 있습니다. image는 이미지를 imagetext는 이미지와 텍스트를 모두 표시합니다. -text는 -itemtype이 text일 때 사용할 수 있으며, -itemtype이 image 때는 대신 -image를, window 일 때는 -window를 사용합니다. 나중에 나옵니다만, -itemtype이 imagetext 경우 -text와 -image 옵션을 사용합니다. 어떤 옵션을 사용할 수 있는지는, 매뉴얼의 Display Items를 참조하세요.

그리드 (tixGrid) 2

이번은 앞 글에 이어 이미지 데이터를 셀에 붙여 넣는 방법과 키보드로 셀을 편집하는 방법에 대한 글입니다.

package require BWidget
package require Tix
wm title . "품목"
proc CBFormat {w area x1 y1 x2 y2} {
        case $area {
                main {
                        $w format grid $x1 $y1 $x2 $y2 \
                                -bd 1 -bordercolor #606060 -relief raised \
                                -bg #c0c0c0 -fill 1
                }
                x-margin {
                        $w format grid $x1 $y1 $x2 $y2 \
                                -bd 1 -bordercolor #606060 -relief raised \
                                -bg #f0c0c0 -fill 1
                }
                y-margin {
                        $w format grid $x1 $y1 $x2 $y2 \
                                -bd 1 -bordercolor #606060 -relief raised \
                                -bg #c0c0f0 -fill 1
                }
                s-margin {
                        $w format grid $x1 $y1 $x2 $y2 \
                                -bd 1 -bordercolor #606060 -relief raised \
                                -bg #f0f0f0 -fill 1
                }
        }
}

proc EditNotifyCmd {w x y} {
        if {$x == 0 || $y == 0} {
                tk_messageBox -message "제목은 편집이 안됩니다."
                return 0
        } else {
                set currentValue [$w entrycget $x $y -text]
                if { $currentValue == "-" } {
                        return 0
                } else {
                        return 1
                }
        }
}

proc EditDoneCmd {w x y} {
        set newValue [$w entrycget $x $y -text]
        tk_messageBox -message "{$x, $y} = ${newValue}..."
}

set f [frame .f]
set g [tixGrid $f.g -width 8 -height 6 \
        -format "CBFormat $f.g" \
        -xscrollcommand "$f.scrh set" \
        -yscrollcommand "$f.scrv set" \
        -editnotify "EditNotifyCmd $f.g" \
        -editdone "EditDoneCmd $f.g"]
set scrv [scrollbar $f.scrv -ori v -com "$g yview"]
set scrh [scrollbar $f.scrh -ori h -com "$g xview"]
grid $g -row 0 -column 0
grid $scrv -row 0 -column 1 -sticky ns
grid $scrh -row 1 -column 0 -sticky ew

$g size col 0 -size 16char
$g set 0 0 -itemtype text -text 품목
set RowTitles [list 고등어 삼겹살 햄버거 생선 튀김 고추 계란 냉면]

set y 1
foreach e $RowTitles {
        $g set 0 $y -itemtype imagetext -text $e -image [Bitmap::get palette]
        incr y
}

set ColTitles {10 11 12 13 14 15 16 17 18}
set x 1
foreach e $ColTitles {
        $g size col $x -size 4char
        $g set $x 0 -itemtype text -text $e
        incr x
}

set data {
  {2 * * 2 * * 2 * *}
  {1 3 * 2 * 1 3 * 2}
  {1 * 4 * 1 3 * 2 1}
  {* * * 2 * * * 3 *}
  {1 * 1 * * * 1 * *}
  {* 3 * * * 3 * * 2}
  {* * 2 2 * * 2 2 *}
  {* 1 1 * * 1 1 * 1}
}
set y 1
foreach e $data {
        set x 1
        foreach d $e {
                $g set $x $y -itemtype text -text $d
                incr x
        }
        incr y
}
ttk::button .b -text "Exit" -command exit
pack $f .b -side top -anchor e
# end.

 

셀을 편집할 수 있도록 하려면 tixGrid 옵션 -editnotify를 사용하며, 옵션 값으로 콜백 프로시져를 지정합니다. 이 프로시져는 x와 y 좌표의 셀이 편집 시 자동으로 불리며, 반드시 1, 0의 값을 반환해야 합니다. 1을 반환하면 셀 (x, y)은 편집 가능, 0을 반환하면 수정 불가능입니다.

proc EditNotifyCmd {w x y} {
...
}

옵션 입니다만, 사용자가 셀을 편집하고 포커스를 벗어나려는 순간에 무언가 작업을 하고 싶다면, tixGrid 옵션 -editdonecmd에 프로시져를 지정합니다.

proc EditDoneCmd {w x y} {
        set newValue [$w entrycget $x $y -text]
        tk_messageBox -message "{$x, $y} = ${newValue}..."
}

이미지 출력 시는 -itemtype 표준인 text 대신 imagetext를 지정하며, set 하위 커맨드로 이미지를 지정합니다.

$g set 0 $y -itemtype imagetext -text $e -image [Bitmap::get palette]

또한 셀 텍스트 또는 이미지 데이터는 entryconfigure 하위 커맨드로 변경이 가능하고, 현재 설정된 값은 entrycget 하위 커맨드로 알 수 있습니다. 

set oldValue [$w entrycget 0 4 - text]
$w entryconfigure 0 4 - text "새우"

계층 구조 리스트 (tixHList)

Tix의 tixHList는 트리 형태의 계층 구조를 표현할 수 있는 리스트 박스와 같은 위젯입니다.

package require Tix
wm title . "TixHList #1"
set fa [frame .fa]
set ha [tixHList $fa.ha \
        -bg #c0c0c0 \
        -relief groove \
        -highlightcolor white \
        -selectbackground #600040 \
        -selectforeground white \
        -width 40 \
        -height 10 \
        -separator . \
        -yscrollcommand "$fa.scrv set"]
set scrv [scrollbar $fa.scrv -ori v -command "$fa.ha yview"]
pack $ha -side left -fill y
pack $scrv -side left -fill y

$ha add a -text "a"
$ha add a.a1 -text "a-1"
$ha add a.a2 -text "a-2"
$ha add a.a3 -text "a-3"
$ha add a.a4 -text "a-4"
$ha add b -text "b"
$ha add b.b1 -text "b-1"
$ha add b.b2 -text "b-2"
$ha add c -text "c"
foreach e [list "c-1" "c-2" "c-3"] {
        $ha add c.$e -text $e
}

ttk::button .cmda -text "Exit" -command exit
pack $fa .cmda -side top -anchor e
# end.

 

위의 예제는 가장 간단한 예제입니다. 계층 구조 리스트는 tixHList 커맨드로 생성합니다. 스크롤 기능을 가진 tixScrolledHList라는 위젯도 있지만, 역시 tixHList만 설명합니다.

set ha [tixHList $fa.ha \
        -bg #c0c0c0 \
        -relief groove \
        -highlightcolor white \
        -selectbackground #600040 \
        -selectforeground white \
        -width 40 \
        -height 10 \
        -separator . \
        -yscrollcommand "$fa.scrv set"]

tixHList 옵션 중 컬러나 외관에 대한 옵션은 Tk의 리스트 박스와 대부분 같습니다. -width와 -height은 문자수를 지정합니다. 특이한 옵션은 -separator입니다. 계층 구조 리스트의 각 항목은 파일 시스템 경로와 같이 구분자로 표현합니다. 기본 구분 기호는 (마침표)입니다.

set ha [tixHList $fa.ha \
        -bg #c0c0c0 \
        -relief groove \
        -highlightcolor white \
        -selectbackground #600040 \
        -selectforeground white \
        -width 40 \
        -height 10 \
        -separator . \
        -yscrollcommand "$fa.scrv set"]

항목을 추가 시 add 서브 커맨드를 사용합니다. 그 첫 번째 인수가 각 항목을 고유하게 식별하고, 계층 구조 안에서의 위치 관계를 표현하는 대표되는 "이름"입니다. add 서브 커맨드는 -itemtype 옵션을 사용하여 지정할 수 있고, image와 imagetext를 지정하면 이미지 데이터를 항목에 표시할 수 있습니다. 계층 구조 출력 시 관계를 나타내는 선을 숨기고 싶은 경우에는, tixHList 옵션 -drawbranch 0을 지정하면 됩니다. 다음 예제는 컬럼을 추가하여 추가 항목을 표시해보도록 하겠습니다. 

package require Tix
wm title . "TixHList #2"
set fa [frame .fa]
set ha [tixHList $fa.ha \
        -bg #c0c0c0 \
        -relief groove \
        -highlightcolor white \
        -selectbackground #600040 \
        -selectforeground white \
        -width 50 \
        -height 10 \
        -separator . \
        -yscrollcommand "$fa.scrv set" \
        -header 1 -columns 4]
set scrv [scrollbar $fa.scrv -ori v -command "$fa.ha yview"]
pack $ha -side left -fill y
pack $scrv -side left -fill y

$ha header create 0 -text {}
$ha header create 1 -text "개시일"
$ha header create 2 -text "판매자"
$ha header create 3 -text "실적"
$ha col width 0 -char 15
$ha col width 1 -char 18
$ha col width 2 -char 10
$ha col width 3 -char 10

$ha add product -text "기획상품"
set s {
        {b 봄상품 2009/02/11 홍길동 90}
        {c 여름상품 2009/04/28 김철수 120}
        {d 가을상품 2009/07/20 박영희 80}
        {e 겨울상품 2009/10/10 마동탁 75}
}

foreach e $s {
        set ename "product.[lindex $e 0]"
        $ha add $ename -text [lindex $e 1]
        $ha item create $ename 1 -text [lindex $e 2]
        $ha item create $ename 2 -text [lindex $e 3]
        $ha item create $ename 3 -text [lindex $e 4]
}

$ha add product2 -text "제품"
set s {
        {f 빈폴 2009/09/23 김태희 190}
        {g 꼼빠니아 2009/11/03 이연희 2000}
}

foreach e $s {
        set ename "product2.[lindex $e 0]"
        $ha add $ename -text [lindex $e 1]
        $ha item create $ename 1 -text [lindex $e 2]
        $ha item create $ename 2 -text [lindex $e 3]
        $ha item create $ename 3 -text [lindex $e 4]
}

ttk::button .cmda -text "Exit" -command exit
pack $fa .cmda -side top -anchor e
# end.

컬럼 추가는 -columns 옵션으로 표시할 열 수를 지정합니다. 또한 위젯의 헤더를 출력하고자 한다면 -header 1을 지정합니다.

set ha [tixHList $fa.ha \
        -bg #c0c0c0 \
        -relief groove \
        -highlightcolor white \
        -selectbackground #600040 \
        -selectforeground white \
        -width 50 \
        -height 10 \
        -separator . \
        -yscrollcommand "$fa.scrv set" \
        -header 1 -columns 4]

옵션의 대부분은 한 번 지정후 차후 configure 서브 커맨드로 다시 설정이 가능하지만, - columns 은 예외입니다. 열 수는 처음으로 위젯을 만들 때만 설정할 수 있으며, 나중에 변경할 수없습니다. 다음은 각 열의 너비와 제목을 설정합니다. 제목은 header create의 -text로, 열의 폭은 column width의 -char 옵션을 사용합니다.

$ha header create 0 -text {}
$ha header create 1 -text "개시일"
$ha header create 2 -text "판매자"
$ha header create 3 -text "실적"
$ha col width 0 -char 15
$ha col width 1 -char 18
$ha col width 2 -char 10
$ha col width 3 -char 10

이 명령의 첫 번째 인수는 열 인덱스로 왼쪽부터 차례로 0,1,2...로 지정합니다. 이 예제에서는 0으로 컬럼을 생성하지만, 화면상 보이는 컬럼의 제목은 표시되지 않습니다. 그러나 -columns 옵션에서 지정한 범위를 넘어서면 오류가 발생합니다. -columns은 정확히 지정해야 합니다.

 

다음글에 이어서 합니다.