ハイアラキカルリスト (2)
 Tixのウィジェットの多くは、 -command-browsecmd というオプションを持っています。 前者はウィジェットがダブルクリックされたときに、 後者は単発でクリックされたときに実行されるプロシージャを登録するもので、 bindコマンドを使わなくてもこれらだけでイベントの処理が可能です。
package require Tix
wm title . "Document Folder III"
image create photo ImageProd -file /usr/icons/p.gif

proc CBclicked {ha e} {
    set itemtext [$ha item cget $e 0 -text]
    eval exec "notepad.exe C:/Temp/$itemtext.txt &"
}
set fa [frame .fa]
set ha [tixHList $fa.ha -bg white -rel groove \
  -highlightcolor white -selectbackground #600040 -selectforeground white \
  -width 40 -height 10 -separator . -yscrollcommand "$fa.scrv set" \
  -command "CBclicked $fa.ha" ]
set scrv [scrollbar $fa.scrv -ori v -command "$fa.ha yview"]
foreach e {ha scrv} {pack $fa.$e -side left -fill y}

# ここからエントリをセットしていきます。
$ha add kikaku -text 企画資料
set s {{haru 春の企画} {natsu 夏の企画} {aki 秋の企画} {fuyu 冬の企画}}
foreach e $s {
     $ha add kikaku.[lindex $e 0] -itemtype imagetext \
       -text [lindex $e 1] -image ImageProd
}
$ha add seihin -text 製品情報
$ha add seihin.marux -text まるこげX
$ha add seihin.maruy -text まるこげY
$ha add juchu  -text 受注実績
foreach e {A1 A2 A3} { $ha add juchu.$e -text $e }

button .cmda -text 終了 -command exit
pack $fa .cmda -side top -anc e
# end.

スクリーンショット

このように、ハイアラキカルリストの項目にも画像データを貼り付けることができます。 やり方はaddサブコマンドの -itemtype に image または imagetext を指定し、さらに -image オプションで画像データを指定すればOKです。

$ha add kikaku.haru -itemtype imagetext -text 春の企画 -image ImageProd

 さて、ツリー構造を表す線の部分には、 「インジケータ」と呼ばれるシンボルをつけることができます。 WIndowsのエクスプローラで、フォルダが展開されていれば−マークが、 閉じられていれば+マークがフォルダのかばん画像の左に現れますが、 ちょうどあれのようなものです。 ただし開いたり閉じたりは自動的には行われず、 そのように動いてほしければそのように処理を書いてやる必要があります。
package require Tix
package require photoattach
wm title . "Document Folder IV"

image create photo ImageKey  -file /usr/icons/pass.gif
image create photo ImageProd -file /usr/icons/p.gif

set fa [frame .fa]
set ha [tixHList $fa.ha -bg white -rel groove \
  -highlightcolor white -selectbackground #600040 -selectforeground white \
  -width 40 -height 10 -separator . -yscrollcommand "$fa.scrv set" \
  -indicator 1 -indicatorcmd "CBind $fa.ha" -indent 50 -font 7x14]
set scrv [scrollbar $fa.scrv -ori v -command "$fa.ha yview"]
foreach e {ha scrv} {pack $fa.$e -side left -fill y}

proc CBind {ha entry} {
    set v [$ha indicator cget $entry -image]
    if {! [string compare $v ImageKey]} {
	set s ImageProm
    } else {
	set s ImageKey
    }
    $ha indicator configure $entry -image $s
}

# ここからエントリをセットしていきます。
# -state disabledにすると選択状態にできなくなります。
$ha add kikaku -text 企画資料 -state disabled
set s {{haru 春の企画} {natsu 夏の企画} {aki 秋の企画} {fuyu 冬の企画}}
foreach e $s {
     $ha add kikaku.[lindex $e 0] -itemtype imagetext \
       -text [lindex $e 1] -image ImageProd
}
$ha add seihin -text 製品情報 -state disabled
$ha add seihin.marux -text まるこげX
$ha add seihin.maruy -text まるこげY
$ha add juchu  -text 受注実績 -state disabled
foreach e {A1 A2 A3} {
    set ename [$ha add juchu.$e -text $e]
    $ha indicator create $ename -itemtype image -image ImageKey
}
button .cmda -text 終了 -command exit
pack $fa .cmda -side top -anc e
# end.

スクリーンショット

 インジケータを使うにはtixHListのオプションに -indicator 1をつけておく必要があり、 また実際にインジケータをつけたい項目に対して、 indicator create サブコマンドでインジケータを作ってやります。 インジケータにも -itemtype として text や image や imagetext が指定できますが、通常 image を使うことになるでしょう。 ちなみにこのサンプルでは背景が透明でない画像をインジケータに使っているのであまりきれいではないです。 インジケータに使う画像は背景を透明に! これをぜひスローガンに。

    set ename [$ha add juchu.$e -text $e]
    $ha indicator create $ename -itemtype image -image ImageKey

 ちなみにインジケータがクリックされたときに実行したいコマンドは tixHListの -indicatorcmd オプションで指定できるので、 ここで自分の子項目を隠したり、 表示したりすることでエクスプローラのような開いたり閉じたりを実装することが可能です。 そこまで自動でやってくれないのかなあ、 と調べてみましたが、自動ではしてくれないようです。 仕方ないのでそのためのヒントを少々…
項目$entryの子項目のリストを得るには
set children [$ha info children $entry]
項目$entryを非表示にするには
$ha hide entry $entry
項目$entryが現在非表示になっているかを知るには
set status [$ha info hidden $entry]
項目$entryを表示するには
$ha show entry $entry
というわけで、これらを使えばディレクトリツリーも作れますね、 といったところで「つなぎ」はOK。 実はその機能までを既に実装しているtixDirListtixDirTree というウィジェットもあるので、 画像を駆使したコテコテのディレクトリツリーを描く必要がなければ、 そちらを使うほうがよいでしょう。 ただアプリケーション内部のみで仮想的なドキュメントの階層構造を表現したい、 などという場合にはこの tixHList で作りこみを行うことになるので、 インジケータの「低層的な」動作について知っておくと役に立つことがあったり、 なかったり。(自信なさげ)


 最後に、プチトマトがトマトの一種であるように、 ハイアラキカルリストもリストも一種です (関係ない関係ない)。 そこで項目の選択状態を知ったり、強制的に変更したりすることも可能なので、 その方法についてメモっておきましょう。
package require Tix
wm title . "Document Folder V"

set fa [frame .fa]
# -browsecmdや-commandオプションでクリックまたはダブルクリックされたときの
# コールバックをさせることもできます。
set ha [tixHList $fa.ha -bg #c0c0c0 -rel groove \
  -highlightcolor white -selectbackground #600040 -selectforeground white \
  -width 40 -height 10 -separator . -yscrollcommand "$fa.scrv set" \
  -header 1 -columns 3]
set scrv [scrollbar $fa.scrv -ori v -command "$fa.ha yview"]
foreach e {ha scrv} {pack $fa.$e -side left -fill y}

# ヘッダ
$ha header create 0 -text {}
$ha header create 1 -text 作成日
$ha header create 2 -text 担当者

$ha col width 0 -char 15
$ha col width 1 -char 18

# ここからエントリをセットしていきます。
$ha add kikaku -text 企画資料
set s { {haru  春の企画 2001/02/11 山田}
        {natsu 夏の企画 2001/04/28 北浦}
        {aki   秋の企画 2001/07/20 北浦}
        {fuyu  冬の企画 2001/10/10 山田} }
foreach e $s {
    set ename kikaku.[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 add seihin -text 製品情報
set s { {marux まるこげX 2000/09/23 坂本}
        {maruy まるこげY 2000/11/03 加藤} }
foreach e $s {
    set ename seihin.[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 add juchu  -text 受注実績
foreach e {A1 A2 A3} {
    set ename [$ha add juchu.$e -text $e]
    $ha item create $ename 1 -text 秘密じゃ
}

$ha selection set kikaku.natsu

proc selected hlist {
    set selectedEntries [$hlist info selection]
    # エントリ名からデータを取り出すには item cgetサブコマンドを使います。
    foreach ename $selectedEntries {
        set t           [$hlist item cget $ename 0 -text]
        set createdDate [$hlist item cget $ename 1 -text]
        set createdBy   [$hlist item cget $ename 2 -text]
        tk_messageBox -message \
"文書「$t」は${createdDate}に${createdBy}によって作成されています。"
    }
}

set fb [frame .fb]
button .fb.cmda -text OK -command "selected $ha"
button .fb.cmde -text 終了 -command exit
foreach e {cmda cmde} {
    pack $fb.$e -side left
}
pack $fa $fb -side top -anc e
# end.

スクリーンショット

 ある項目を強制的に選択状態にするには selection setサブコマンドを使います。

$ha selection set kikaku.natsu

 また現在選択されている項目のエントリ名 (複数選択されていれば、そのリスト)を知るには、 info selectionサブコマンド (selection getも同義)を使います。 これは選択状態にあるエントリ名(インデックスではないので注意!) を返します。 エントリ名からその見出し文字列を取得するには、 既に出てきたと思いますが item cgetサブコマンドで列位置0を指定すればOKです。

    set ename [$ha info selection]
    set t [$ha item cget $ename 0 -text]

拡張レビュー分室 top
(first uploaded 2001/04/13 last updated 2001/04/17, MISUMI URANO)