BLT는 벨 연구소에서 개발되고, 루슨트 테크놀로지에 저작권이 있는, Tk와 더불어 최대의 Tk 확장 라이브러리 세트입니다. Tk의 순수한 기능 확장으로 예전부터 잘 알려져 있습니다. BLT가 무엇의 약자인지는 매뉴얼을 읽어봐도 "원하는 대로 해석하세요"라고만 나와 있으니, "Beautiful Lady and Television"의 약자라고 우겨도 틀리지 않습니다.
BLT의 현재 버전은 2.4z (2002/10/15)이고, [이곳] 에서 다운로드할 수 있습니다. Tcl/Tk의 7.5, 7.6, 8.0 이후의 각 버전을 지원합니다. 2.4p부터는 스텁(stub) 메커니즘을 지원하여, 8.2용 BLT는 8.3 이후 버전에서도 사용할 수 있습니다. 반면, 7.* 버전에 대한 지원은 점점 사라지고 있는 듯합니다.
주요 기능으로는 다음과 같습니다.
- 다양한 2차원 X-Y 그래프
- 계층적 리스트박스
- GUI 위젯에 배경 이미지를 붙일 수 있는 확장
- 탭이 달린 패널
- "busy" 윈도우
- 테이블 형태의 지오메트리 매니저
- 윈도우를 Tk 이미지로 캡처하기
이 모든 기능은 우리 GUI 애플리케이션에 강렬한 외관을 부여해줍니다. 기능이 강력한 만큼 매우 복잡하지만, 함께 제공되는 HTML 문서가 잘 정리되어 있어 이것을 참고하면 쉽게 익숙해질 수 있습니다. 바로 사용해봅시다!
리눅스용 설치
리눅스에서는 익숙한 configure → make → make install 과정으로 설치하면 됩니다. 다만, 실행 프로그램(bltwish)을 만드는 것보다 공유 라이브러리(libBLT24.so)를 만들어 설치하는 쪽이 여러모로 더 편리합니다.
% sh configure
% cd src/shared
% make
# make install
% cd ../../library
% make
# make install
/usr/local에 설치한 경우, 공유 라이브러리 libBLT24.so는 /usr/local/lib/에, 초기 설정용 Tcl 스크립트는 /usr/local/lib/blt2.4에 복사됩니다.
윈도우즈용 설치
Windows용 BLT는 Tcl/Tk 와 함께 컴파일된 바이너리 버전을 자체 설치 파일 형태로 배포되기 때문에 설치가 매우 간단합니다. 파일을 다운로드하면, 아주 깔끔한 인스톨러가 등장합니다. Tcl/Tk 자체 설치 보다도 더 신경 써서 만든 듯한 설치 화면에서 제작자의 센스를 느낄 수 있습니다. (현재 제공되는 설치 파일은 16비트 윈도우즈 95 만 지원하는것 같습니다. 현재의 윈도우즈 7이나 11에서는 설치가 불가합니다. 리눅스의 설치 방법과 마찬가지로 msys2 환경에서 MinGW 컴파일러를 사용하여 빌드가 가능합니다.)
설치 위치를 물어보면, 이미 Tcl/Tk 가 설치된 디렉터리(예: `C:\Program Files\TCL`)를 지정하면 됩니다. 물론 다른 디렉터리(예: `C:\Program Files\BLT`)를 지정해도 됩니다.
설치가 완료되면, `bin` 서브디렉터리 아래에 WISH84.EXE에 BLT가 포함된 인터프리터인 "BLTWISH.EXE"와, load 명령어로 로드할 수 있는 DLL 파일인 "BLT24.DLL"이 생성됩니다. 일반적으로는 BLT24.DLL을 로드해서 사용하는 쪽이 더 편리할 것입니다.
BLT 사용하기
BLT 기능을 사용하는 Tcl 스크립트의 맨 앞에는 다음과 같은 코드를 작성합니다.
package require BLT
namespace import blt::*
namespace import -force blt::tile::*
이름공간(namespace)이 갑자기 등장하지만, 위와 같이 코드를 작성해두면 이후에 BLT의 기능을 사용할 때 이름공간을 신경 쓸 필요가 없어집니다. 그래서 매번 스크립트의 맨 앞부분에 이렇게 적어두는 것이 좋습니다.
선 그래프 그리기
BLT에서 제공하는 그래프는 모두 X-Y 2차원 그래프입니다. 그래프의 종류로는 `graph`, `barchart`, `stripchart`가 있습니다. 하지만 기본 사용법은 거의 동일하므로 여기서는 대표적으로 `graph`를 사용합니다. `graph`, `stripchart`는 선 그래프, `barchart`는 막대그래프입니다.
package require BLT
namespace import blt::*
namespace import -force blt::tile::*
wm title . "BLT 샘플 1"
set temperature {5 10 15 20 25 30 35 40 45}
set di {81.2 72.5 43.4 5.6 18.2 60.9 98.2 99.9 99.8}
pack [set g [graph .g -plotbackground black]]
$g configure -title "온도와 사람의 불쾌지수 관계"
$g element create line1 -xdata $temperature -ydata $di
$g element configure line1 -label {2001.7 조사} \
-symbol square -pixels 4 -color "#ffcc00" -fill "#800000" \
-outline "#ff0000" -outlinewidth 1 \
-dashes {2 4 2} -linewidth 2 -trace increasing
# symbol: square, circle, diamond, plus, cross, splus, scross, triangle, ""
$g element show
$g axis configure x -title 온도
$g axis configure y -title 불쾌지수
# 마우스 조작으로 확대, 축소
bind $g <ButtonPress-1> {
%W axis configure x -min [%W axis invtransform x %x]
%W axis configure y -min [%W axis invtransform y %y]
}
# 원래대로 되돌리기
bind $g <ButtonPress-3> {
%W axis configure x -min {}
%W axis configure y -min {}
}
$g legend configure -position right -relief groove -font fixed -fg blue
$g crosshairs configure -hide no -color red -dashes {2 2} -linewidth 2
Blt_Crosshairs $g
$g grid configure -hide no -dashes { 2 2 }
X축과 Y축 데이터 준비
기본적으로 두 축 모두 숫자 축입니다. 아래 예시처럼 각각 숫자로 이루어진 두 개의 리스트를 준비해도 되고, BLT에서 확장된 데이터 구조인 벡터(vector)를 사용할 수도 있습니다.
여기서는 "기온(섭씨)"과 "불쾌지수(%)" 데이터를 예로 들었습니다. 40도에서 45도로 갈 때 불쾌지수가 줄어드는 것은, “그 사이에 깨달음의 경지에 도달해서 불도 시원하게 느껴진다”는 이상한 답변을 한 사람이 한 명 있었기 때문입니다.
set temperature {5 10 15 20 25 30 35 40 45}
set di {81.2 72.5 43.4 5.6 18.2 60.9 98.2 99.9 99.8}
그래프 생성 및 표시
그래프는 독립적인 Tk 위젯으로 관리되므로, “.g”처럼 이름을 붙이고, 일반 Tk 위젯처럼 `pack` 할 수 있습니다.
graph .g -plotbackground black
pack .g
.g configure -title "온도와 사람의 불쾌지수 관계"
데이터와 그래프 연결
그래프 위젯(.g)에 데이터 리스트를 붙여서 선그래프로 만듭니다. `element create` 명령을 사용합니다.
.g element create line1 -xdata $temperature -ydata $di
선(데이터 시리즈) 설정
선(데이터 시리즈)에 대한 각종 옵션을 `element configure`로 설정합니다.
.g element configure line1 -label {1999.7 조사} \
-symbol square -color red -dashes {2 4 2} -linewidth 2
.g element show
- -label : 범례에 표시될 이름
- -symbol : 데이터 점의 모양
- -color : 선 색상
- -dashes : 선의 점선 패턴
- -linewidth : 선 두께
좌표축 설정
.g axis configure x -title 온도
.g axis configure y -title 불쾌지수
- -title : 축 제목
`axis configure`의 -min, -max 옵션을 이용하면 그래프를 줌인/줌아웃 할 수 있습니다.
마우스 조작으로 확대/축소
# 왼쪽 클릭: 확대
bind .g <ButtonPress-1> {
%W axis configure x -min [%W axis invtransform x %x]
%W axis configure y -min [%W axis invtransform y %y]
}
# 오른쪽 클릭: 원래대로 복원
bind .g <ButtonPress-3> {
%W axis configure x -min {}
%W axis configure y -min {}
}
범례, 크로스헤어, 그리드 설정
.g legend configure -position right -relief groove -font fixed -fg blue
.g crosshairs configure -hide no -color red -dashes {2 2} -linewidth 2
Blt_Crosshairs .g
.g grid configure -hide no -dashes { 2 2 }
범례, 크로스헤어, 격자선 등도 세밀하게 설정할 수 있습니다. 이런 식으로 하면 BLT의 그래프를 자유롭게 꾸밀 수 있습니다.
계층 구조 리스트박스 (Hierarchical Listbox)
계층 구조 리스트박스란, 쉽게 말해 Windows의 탐색기 왼쪽 부분(트리 구조 폴더 리스트)과 같은 GUI 위젯 입니다. BLT의 hierbox 위젯을 사용하면, 일반적인 Tk 위젯처럼 동일하게 생성할 수 있습니다.
참고로 hierbox 위젯은 BLT 2.4w 버전에서 완전 상위 호환인 treeview 위젯이 등장하면서, 현재는 향후 폐지 예정으로 간주됩니다. 최신 프로젝트에서는 treeview 위젯 사용을 권장합니다.
package require BLT
namespace import blt::*
namespace import -force blt::tile::*
wm title . "BLT 샘플 2"
entry .ea -state disabled
set f [frame .fa -rel groove]
set h [hierbox $f.h -yscrollcommand "$f.scrv set" -height 200]
scrollbar $f.scrv -orient vertical -command "$f.h yview"
grid $f.h -row 1 -column 1
grid $f.scrv -row 1 -column 2 -sticky ns
foreach e {ea fa} {pack .$e -side top -fill x}
$h configure -separator {::}
foreach a {::java ::javax ::javax::swing ::java::io ::java::net ::javax::swing::table
::javax::naming ::javax::naming::directory} {
$h insert end $a
}
bind $h <Double-Button-1> {
if {"[set i [%W curselection]]" != ""} {
.ea configure -state normal
.ea delete 0 end
.ea insert end "[%W get $i] : [%W get -full $i]"
.ea configure -state disabled
}
}
기본 사용법
hierbox .h -yscrollcommand {.scrv set} -height 200
scrollbar .scrv -orient vertical -command {.h yview}
hierbox 커맨드는 일반 Tk 위젯처럼 사용하고, insert, delete, curselection, get 등 주요 조작법도 listbox와 거의 동일합니다.
계층 구조 구성
계층 구조(트리)를 만들려면, 먼저 `configure`의 `-separator` 옵션으로 계층 구분 문자를 지정합니다.
.h configure -separator {::}
foreach a {::java ::java::awt ::java::io ::java::net ::java::awt::event} {
.h insert end $a
}
예를 들어, "::java::awt"라는 항목은 루트 아래 "java" 폴더, 그 아래 "awt" 폴더가 생기는 구조를 의미합니다.
선택 항목 패스 반환
bind $h <Double-Button-1> {
if {"[set i [%W curselection]]" != ""} {
.ea configure -state normal
.ea delete 0 end
.ea insert end "[%W get $i] : [%W get -full $i]"
.ea configure -state disabled
}
}
위와 같이 트리 항목을 더블 클릭시 현재 선택된 노드의 풀 패스를 표시합니다. `get -full` 옵션을 사용하면, 트리의 전체 경로가 반환됩니다.