| |
Tktableは、「table」という名前のTk拡張ウィジェットを追加するライブラリです。
tableウィジェットは、表形式で2次元のデータを表示・編集することができるもので、
標準Tkではなかなかできないデータシート操作を実現できます。
Tktableはオープンソース・ソフトウェアで、
SourceForgeで無償で入手できます。
また、
Windows用のTcl/Tkバイナリ配布である
ActiveTclにも同梱されています。
現在の最新版はバージョン2.10です。
package require Tktable
set glob "/home/mamemiya/tcl/*"; set files [glob -nocomplain $glob]
set files [glob -nocomplain $glob]
set tabtab(0,1) "ファイル名"
set tabtab(0,2) "タイプ"
set tabtab(0,3) "モード"
set tabtab(0,4) "編集時刻"
set y 1
foreach path $files {
file stat $path a
set tabtab($y,1) [file tail $path]
set tabtab($y,2) $a(type)
set tabtab($y,3) [string range [format %o $a(mode)] 2 end]
set tabtab($y,4) [clock format $a(mtime) -format "%Y-%m-%d %H:%M"]
incr y
}
table .t -rows $y -cols 4 -variable tabtab -titlerows 1 -titlecols 0 \
-roworigin 0 -colorigin 1 -font {Helvetica 12 normal}
pack .t
bind . <Button-3> exit
|
tableウィジェットはtableコマンドで作ります。ってあたりまえか。
それで、-rowsは行の数、-colsは列の数です。
ここで早くも最初の山です。ええっ2行目にして早くもとかないですから。
Tktableの道は長く険しいのではなくて、短くて超険しいだけですから(帰れ)
えーとそれで、
あー
-rowsの値は、
このウィジェットの縦のサイズ(つまり高さ)
を行数分で指定するためのものではありません。
-heightで指定するテーブルのウィジェットとしての高さとも全然関係なく、
後述の-variableの配列変数が持っている行データの数をそのまま指定する必要があります。
-variableが最初の重要なオプションで、配列の変数の名前を指定します。
2次元のデータだからリストのリストで指定するのかと思いきや、そうではありません。
(行,列)の2次元の添字を持つ配列変数で指定するのです。
(行,列)ですから(x,y)ではなく、(y,x)となるのに注意してくださいね。
この添字はセルの数だけ全て値を代入しておく必要はなくて、
値を代入してないセルは空欄になるので大丈夫です。
そんでそんで、
-titlerowsは表の上端に、-titlecolsは表の左端に表示する見出しセルの数です。
スクリーンショットとスクリプトを見比べて頂くと、
-titlerowsが1なので上端に見出し行が1行あり、-titlecolsが0なので左端には見出し行はありません。
そんでそんでそんで、-roworiginと-coloriginが使い方次第では面白いオプションで、
配列変数の添字が行、列それぞれ何から始まるかを指定するものです。
簡単に言うと、左上隅のセルの値を持つ配列変数の添字を指定するのです。
つまり、この例は左上隅は 「tabtab(0,1)」なので-roworiginは0、-coloriginは1というわけです。
最後に-fontなど、普通のTkウィジェットが持っているオプションの多くはtableでも使えます。
これで一応tableウィジェットでファイル一覧を表示できました。
デフォルトで、見出しセルは編集できませんが、見出しでないセルはキー入力で編集できます。
MS-Excelみたいにセルが編集できるのか!と喜んでキーボードをいろいろ叩いてみると、
最初はちょっと面食らうと思います。
というのは多分、Backspaceで削ることはできるけど、
カーソルキーで文字列の間にカーソルを動かすことはできないのか!?
そんなの今時、使えへんーーーー!!!!
と思うことでしょう。
…実は、セル内の入力カーソルの移動はCTRL+カーソルキーの左右で行えます。
デフォルトのキーバインディングがちょっとトリッキーで、Excelとは全然違うのでまごまごチックです。
一応、マニュアルの「デフォルトのキーバインディング」を、簡単に訳してみました。
| キー | 操 作 |
| マウス左クリック |
クリックされたセルをアクティブにする。既にアクティブなセルをつついた場合は、
その震源に最も近い位置に入力カーソルを表示する
|
| HOME | 左上端のセルに移動 |
| END | 右下端のセルに移動 |
| CTRL+HOME | 左上端のセルに移動し、そのセルをアクティブにする |
| CTRL+END | 右下端のセルに移動し、そのセルをアクティブにする |
| SHIFT+CTRL+HOME | 左上端のセルまで選択範囲を広げる |
| SHIFT+CTRL+END | 右下端のセルまで選択範囲を広げる |
| カーソルキー | アクティブなセルを移動させる |
| SHIFT+カーソルキー | カーソルキーの方向に選択範囲を広げる |
| CTRL+左右のカーソルキー |
セル内の入力カーソルを左右に移動させる |
| CTRL+/ | 全てのセルを選択状態にする |
| CTRL+\ | 全てのセルを非選択状態にする |
| BACKSPACE | 入力カーソルの前の文字を削除する |
| DELETE | 入力カーソルの後ろの文字を削除する |
| ESCAPE | 編集を破棄してセルの元の値を再度読み込む |
| CTRL+A | 入力カーソルの先頭に移動させる |
| CTRL+E | 入力カーソルの末尾に移動させる |
| CTRL+- | 現在アクティブなセルの列幅を狭くする |
| CTRL+= | 現在アクティブなセルの列幅を広くする |
なんじゃこりゃ?Excelと全然違うやん。
少しでもExcel伝統の動きに近づけるには?
実は捨てる神あれば拾う神あり、じゃなかった、何?
Excelと違うバインディングにするTktableあれば
Excelと同じバインディングあり(なんじゃそりゃ)、
そうそう、バインディングを変更すれば何とかなるのです。
bind Table <Tab> {::tk::table::MoveCell %W 0 1}
bind Table <Shift-Tab> {::tk::table::MoveCell %W 0 -1}
bind Table <Return> {::tk::table::MoveCell %W 1 0}
bind Table <Shift-Return> {::tk::table::MoveCell %W -1 0}
bind Table <Control-b> {%W icursor [expr {[%W icursor]-1}]}
bind Table <Control-f> {%W icursor [expr {[%W icursor]+1}]}
bind Table <Left> {%W icursor [expr {[%W icursor]-1}]; break}
bind Table <Right> {%W icursor [expr {[%W icursor]+1}]; break}
|
| キー | 操 作 |
| カーソルキー | セル内の入力カーソルを左右に移動させる |
| TAB | 右のセルに移動 |
| SHIFT+TAB | 左のセルに移動 |
| ENTER | 下のセルに移動 |
| SHIFT+ENTER | 上のセルに移動 |
| CTRL+B | セル内の入力カーソルを左に移動させる |
| CTRL+F | セル内の入力カーソルを右に移動させる |
また、先ほどの表にはありませんが、
-selectmodeがsingleやextendedの場合、
CTRL+Cキーで選択したセルの値をクリップボードにコピーすることができ、
CTRL+Vキーでクリップボードの値をTktableに貼り付けることができます。
そんでそそそそそんで、それをおいといても、まだかなり不満な出来です。
まず編集時刻の列は幅が狭すぎます。
またファイル名は中央揃えではなく左揃えにしたいのですが。
また、見出し行は背景色を変え、その見出し文字列は太字で表示したいところです。
ということであれこれ改造してみましょう。
以下はその追加分だけです。重複分を省略して地球に優しくしてみました。
# 列4の幅を16文字分に設定します。
.t width 4 16
# タイトル行の背景色、文字色、フォントを設定します。
.t tag configure title -bg "midnightblue" -fg "white" -font {Helivetica 12 bold}
# 列1の行0(見出し行)以外のセルを左揃えにします。
.t tag row row0 0
.t tag col col1 1
.t tag configure col1 -anc w
.t tag configure row0 -anc center
# 列3の各セルをgrooveで囲み、編集不可能にします。
.t tag col col3 3
.t tag configure col3 -rel groove -bd 3 -state disabled
|
tableウィジェットにも標準Tkウィジェットと同様、多数のウィジェットコマンドがあります。
ここではそのうちwidthとtagという2つのコマンドだけを使っています。
特定の列の幅を変更するにはwidthコマンドを、高さを変更するにはheightコマンドを使います。
widthの値は現在のフォントでの文字数(バイト数)です。
幅や高さ以外の属性を変更するには、
「タグ」
とゆーものを定義します。
最初から定義済みのタグが4つあります。active、flash、sel、titleで、
ここで使っているtitleはそのうちの1つであって、見出しセル全部という意味です。
ここではこのタグにtag configureウィジェットコマンドを使って、
背景色、文字色、フォントを変えています。フォントでboldと指定しているので、太字になってます。
それ以外の「何列目」のようなタグを作るには、tag colコマンド(列を指定)、
tag rowコマンド(行を指定)を使います。
そして作ったタグに対して、tag configureで属性を変更します。-ancは-anchorの省略形です。
この目的に使うのは-justifyではなく-anchorのようなので、要注意。
この例では、1列目を左揃えにし、それだと1列目の見出しセルも左揃えになってしまうので、
その上に重ねて1行目を中央揃えにしています。
(このサンプルでは1行目=タイトル行なので、
row0タグを作らなくても、組み込みタグtitleで指定しても同じですが…)
package require Tktable
set glob "/home/mamemiya/tcl/*"; set files [glob -nocomplain $glob]
set tabtab(0,1) "ファイル名"
set tabtab(0,2) "タイプ"
set tabtab(0,3) "モード"
set tabtab(0,4) "編集時刻"
set y 1
foreach path $files {
file stat $path a
set tabtab($y,1) [file tail $path]
set tabtab($y,2) $a(type)
set tabtab($y,3) [string range [format %o $a(mode)] 2 end]
set tabtab($y,4) [clock format $a(mtime) -format "%Y-%m-%d %H:%M"]
incr y
}
table .t -rows $y -cols 5 -colwidth 6 -rowheight -40 \
-variable tabtab -titlerows 1 -titlecols 1 \
-roworigin 0 -colorigin 0 -font {Helvetica 12 normal} \
-selectmode extended -cursor arrow
.t width 1 16
.t width 4 16
.t tag configure title -bg "midnightblue" -fg "white" -font {Helivetica 12 bold}
.t tag row row0 0
.t tag col col1 1
.t tag configure col1 -anc w
.t tag configure row0 -anc center
.t tag col col3 3
.t tag configure col3 -rel groove -bd 3 -state disabled
bind .t <Double-1> {
set c [%W curselection]
tk_messageBox -message $c
}
for {set i 1} {$i<=[expr [.t cget -rows]-1]} {incr i} {
checkbutton .t.ck$i
.t window configure $i,0 -window .t.ck$i
}
pack .t
bind . <Button-3> exit
|
この例のように、tableウィジェットのセルの中に別のウィジェットを埋め込むこともできます。
それには、window configureウィジェットコマンドを使います。
その引数は 「行,列」で位置を指定し、-windowで埋め込むウィジェットを指定します。
但し、セルの値とそのウィジェットに表示する値を同期的に紐付けて連動させることはできません。
それで、チェックボックスを入れるとデフォルトではセルの高さが足りないので、
tableの-widthと-heightでデフォルトのセルの幅と高さを指定しています。
Tktableはこの幅や高さの指定の仕方が結構変わっていて、
正の数で指定すると文字数(高さの場合は段数)、負の数で指定するとピクセルの意味になります。
つまり14と指定すると14文字、-140と指定すると140ピクセルの意味になるということです。
なんでかとか聞いてはなりませぬ。
また、現在選択されているセルを知るには、curselectionというウィジェットコマンドを使います。
これは、選択されているセルの位置を、"行,列"の形の文字列で返します。
この行、列のインデックスは、
見出し行・普通の行の区別なく、左上端のセルを基点としたセルの位置で返されます。
また-roworigin、-coloriginによる補正を受けます。
左上端が(0,0)でない場合、数え間違えないように注意が必要です。
(first uploaded 2005/08/24 last updated 2011/01/08, MISUMI URANO)
|