|
Tixいろいろ (3) 標準Tkで提供されるウィジェットは、 どれもプリミティヴャな機能しか持っていません。 そのため集積的なアプリケーションともなるとたくさんのウィジェットを組み合わせて作りこむ必要があり、 全体のコードが見えにくくなる要因にも成りかねません。 一方、Tkのウィジェット連のシンプルさを補うべく開発された Tixには実用的なアプリケーションを短期間で開発するための高機能なウィジェットが揃っています。 特にここで紹介するウィジェットはファイルシステムのディレクトリ構造に深く関わるウィジェットで、 ファイルの操作を行うアプリケーションの開発に威力を発揮することでしょう。
●ディレクトリリスト
package require Tix
package require pife
wm title . "Image Viewer"
tixDisplayStyle text -stylename redstyle -fg #800040
tixDisplayStyle text -stylename redrightstyle -fg #800040 -anchor e
tixDisplayStyle text -stylename rightstyle -anchor e
# 画面左上、ディレクトリリストを作ります。
# tixDirListの-width -heightはピクセル数です。
# またhlistサブウィジェットのデフォルト背景色は灰色です。
set da [tixDirList .da -root /]
$da subwidget hlist configure -bg white
# 画面右上、ファイルリストを作ります。
# tixScrolledHListは複数のカラムをつけることができません。
# そこで、通常のtixHListとスクロールバーを使います。
set fa [frame .fa]
set ha [tixHList $fa.ha -column 2 -separator / -width 50 \
-xsc "$fa.scrh set" -ysc "$fa.scrv set"]
scrollbar $fa.scrv -ori v -command "$ha yview"
scrollbar $fa.scrh -ori h -command "$ha xview"
grid $ha -row 1 -col 1
grid $fa.scrv -row 1 -col 2 -sticky ns
grid $fa.scrh -row 2 -col 1 -sticky ew
$ha col width 0 -char 15
$ha col width 1 -char 8
# 画面下、画像表示部分を作ります。
# tixScrolledWindow
set sw [tixScrolledWindow .sw -width 450 -height 200]
set swf [$sw subwidget window]
canvas $swf.can -width 300 -height 300 -bg white
pack $swf.can
# コールバックの登録
$da configure -browsecmd "CBdirselected $ha"
$ha configure -command "CBfileselected $da $ha $swf.can"
# ファイルが選択されたときのコールバックプロシージャ。
# 下のキャンバスに画像を表示します。
proc CBfileselected {dlist hlist can filename} {
# tixDirListから現在選択されているディレクトリの絶対パスを得るには
# -valueオプションを使います。
set dname [$dlist cget -value]
set filename [file join $dname $filename]
if {[catch {
$hlist configure -cursor watch; update
image create photo Image1 -file $filename
}]} {
$hlist configure -cursor {}; update; return
}
$can delete all
$can create image 0 0 -anc nw -image Image1
$can configure -width [image width Image1] -height [image height Image1]
$hlist configure -cursor {}; update
}
# tixDirListがシングルクリックされたときのコールバックプロシージャ。
# 選択されているディレクトリの絶対パスが自動的に引数につけられます。
proc CBdirselected {hlist absdirpath} {
set entries [glob -nocomplain [file join $absdirpath *]]
set imageexts {.bmp .gif .jpg .tif .tiff .png .xpm}
# tixHListの項目をクリア
$hlist delete all
# ファイル名を追加します。tixHListの「階層」機能は使わず、
# 単に縦横に項目を並べるために使っています。
foreach fullpath $entries {
set e [file tail $fullpath]
$hlist add $e -itemtype text -text $e
$hlist item create $e 1 -itemtype text \
-text [file size $fullpath] -style rightstyle
# もしファイルが画像っぽい拡張子をもっていたら、赤で目立たせます。
if {[lsearch $imageexts [file extension $e]] != -1} {
$hlist item configure $e 0 -style redstyle
$hlist item configure $e 1 -style redrightstyle
}
}
}
grid $da -row 1 -col 1
grid $fa -row 1 -col 2
grid $sw -row 2 -col 1 -columnspan 2
●ディスプレイスタイル
tixDisplayStyle text -stylename redrightstyle -fg #800040 -anchor e # ... $hlist item configure $e 1 -style redrightstyleディスプレイスタイルはtixDisplayStyle で作ります。フォントは-font、テキストの色は-foregroundや-selectforeground、 背景色は-backgroundや-selectbackgroundなど、 標準Tkのウィジェットオプションと同じなので分かりやすいでしょう。 しかし、右詰・左詰を表すオプションには要注意。一見、 「-justify right」で右詰になりそうですが、はずれ。ブブー、 正解は「-anchor e」です。これには私もはまりました。 ディスプレイスタイルには上のように-stylenameで名前をつけることができ、 この値を-styleオプションで指定すればOKなのですが、-stylename を省略すると適当な名前を生成して返してくるので、 これを下のように使うこともできます。 set redright [tixDisplayStyle text -fg #800040 -anchor e] # ... $hlist item configure $e 1 -style $redright
●スクロールドウィンドウ set sw [tixScrolledWindow .sw -width 450 -height 200] set swf [$sw subwidget window] canvas $swf.can -width 300 -height 300 -bg white pack $swf.canスクロールドウィンドウはtixScrolledWindowコマンドで作ります。 これもラベルフレームと同様、その上に直接他のウィジェットを載せることはできません。 subwidget windowサブコマンドでウィンドウ部分にあたるサブウィジェットを取り出し、 その中にスクロール表示したいウィジェット(ここではキャンバス1個だけですが、 もちろん複数個載せることもできます)をpackします。
●ディレクトリツリー
package require Tix
package require dpu
set trea [tixDirTree .trea \
-browsecmd "CBDirTreeClicked .f2.ha" -directory C:/Install \
-showhidden 1]
set f [frame .f2 -rel groove -bd 2]
set ha [tixHList $f.ha -separator . -header 1 -columns 2 \
-yscrollcommand "$f.scrv set" -xscrollcommand "$f.scrh set" \
-width 40]
scrollbar $f.scrv -ori v -command "$f.ha yview"
scrollbar $f.scrh -ori h -command "$f.ha xview"
grid $f.ha -row 1 -col 1
grid $f.scrv -row 1 -col 2 -sticky ns
grid $f.scrh -row 2 -col 1 -sticky ew
$ha header create 0 -text 名前
$ha header create 1 -text 種類
proc CBDirTreeClicked {ha dirpath} {
set dirpath [lindex $dirpath 0]
# 今の行を全て削除
$ha delete all
# エントリを追加
set i 0
foreach e [glob -nocomplain [file join $dirpath *]] {
$ha add $i -itemtype text -text [file tail $e]
if {[file isfile $e]} {
# 通常ファイルの場合、その説明を追加
if {[catch {set description [magic $e]}]} {
set description "(cannot open)"
}
$ha item create $i 1 -text $description
}
incr i
}
}
pack $trea $f -side left -fill y
# end.
set trea [tixDirTree .trea \ -browsecmd "CBDirTreeClicked .f2.ha" -directory C:/Install \ -showhidden 1]で、他の多くのウィジェットと同様、ディレクトリツリーも -browsecmdで単発クリックされたとき、-commandでダブルクリックされるかENTERが押された場合のコールバックプロシージャを指定することができます。 コールバックプロシージャには、 選択されたディレクトリのフルパスのリストが引数として渡されます。 重大な注意をひとつ。これは 「フルパス」ではなく「フルパスのリスト」です! 両側に{ }がついている場合は、lindexで取り出しましょう。 またWindowsの場合は、このパスはバックスラッシュ区切りで渡されます。
proc CBDirTreeClicked {ha dirpath} {
set dirpath [lindex $dirpath 0]
# ...
}
さて最初の疑問に戻って、
ディレクトリリストとディレクトリツリーはどー違うのか?
ということなんですけど、
よーく見て比べると、むしろものすごく分かりやすい違いが明らかになると思います。
ディレクトリリストは、
選択されているディレクトリから始祖までの直系しか常に表示されないのです。つまり、選択ディレクトリの隣のディレクトリや、
選択ディレクトリの親ディレクトリの隣のディレクトリや、(以下略)
はリストに現れないのです。
ディレクトリツリーは選択ディレクトリの隣のディレクトリも表示されるほか、
マウスでクリックするたびにサブディレクトリが展開されたり閉じられたりします
(ハイアラキカルリストはそのままではサブ項目を展開したり閉じたりはされないことを思い出してください)。
Windowsのエクスプローラの左半分、という機能に近いのは当然、
ディレクトリツリーの方です。
ありゃ、ではディレクトリリストの存在意義は?
|