-IX- Tcl で XXX するには,どうしたらいいの?
A9A. 拡張 Tcl の配列や,キー付きリストを使うと良いでしょう.
例えば,以下のようにプログラムしたなら:
keylset ttyFields ttyName tty1a
keylset ttyFields baudRate 57600
keylset ttyFields parity strip
ここで "echo $ttyFields" を実行すると,以下を得ます:
{ttyName tty1a} {baudRate 57600} {parity strip}
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9B. y は複数の引数を要求し,x は複数の語を返すとします.Tcl の eval
コマンドを使ってやります:
eval y [x]
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9C. もし可能であるならば,グローバル変数を使うよりも,upvar コマンド
を試して見るべきです.もし,関数がイベント駆動であるならば,グローバル
変数を使わざるを得ませんが.
# print elements of an array
proc show_array arrayName {
upvar $arrayName myArray
foreach element [array names myArray] {
puts stdout "${arrayName}($element) = $myArray($element)"
}
}
set arval(0) zero
set arval(1) one
show_array arval
この例のように,引数に対して array names コマンドを使って,引数として
渡された配列にアクセスできます.配列に対して行った変更は,呼び出し側の
配列に対しても行われます.
拡張 Tcl は,キーと値の組合せのリストである,キー付きリストと呼ばれる
コンセプトを導入していて,ネットワーク経由などでも,値をルーチンに引き
渡すことが出来ます.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9D. 例えば,ファイルで指定できる範囲を越えたパターンマッチを grep で
やるには,以下の方法などが考えられます:
[email protected] (Karl Lehenbauer) が書く所によれば:
set files [glob /home/cole/stats/*]
proc parseInfo { site } {
global files
#
# site is chosen from a listbox earlier
#
set in [open [concat "|/usr/bin/grep $site $files"] r]
while {[gets $in line]>-1} {
puts stderr $line
}
catch {close $in}
}
問題点: マッチした文字列が,ディレクトリ順に戻ら*ない*.
一方,もし,リターン・コードをチェックし,かつ,コマンドの出力を使いた
いならば, [email protected] (Kevin B. Kenny) の書く所によれば:
if [catch {exec ls} data] {
# The exec got an error, and $errorCode has its termination status
} else {
# The exec succeeded
}
# In any case, `data' contains all the output from the child process.
Karl Lehenbauer が errorCode を,文字列 "CHILDSTATUS",子プロセスのプ
ロセス ID,子プロセスの終了ステータスの 3 つの要素を持つリストとして加
えた点に注意して下さい.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9E. 拡張 Tcl の最新バージョンである tclX 6.7c では,他のアプリケーショ
ンと合体させやすい様に改良されています.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9F. rename プロシージャ名 ""
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9G. 1992 年 6 月現在,upvar に,配列の個々の要素を書くことはできませ
ん.これは,Ousterhout 氏にバグであると確認され,バグリストに置かれて
います.
[訳注: ファイル changes によれば,93 年 4 月 29 日付けで,この問題は
fix されているようです.]
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9H. Tcl 6.x では,tclExpr.c モジュールの %g を使っている所を %lf を使
うように書き換えます.Tcl 7.x では,グローバル変数 tcl_precision を
set します.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9I. 見付けられないコマンドが呼び出された際には,プロシージャ
"unknown" が,(見付けられなかった)コマンド名とその引数を引数にして自動
的に呼び出されます.実際の所,Tcl と 拡張 Tcl は,この機能を,コマンド
やライブラリの自動読み込みの機能を実現するのに使用しています.
従って,unknown プロシージャを書き換えれば,独自の機能拡張を行えます.
望むならば,自動読み込みの機能を削除することさえも可能です.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9J. 例えば,次のように行います.
set olddisplay $env(DISPLAY)
set env(DISPLAY) unix:0
答えてくれた "Joel Fine" に感謝します.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9K. Dave Morriss は,最近,この問題を抱えてたため,次のように書いて見
ました.
set index [expr [exec date +%W]%[llength $pop_server_list]]
しかしながら,8 番目と,9 番目の週でエラーとなってしまいました.---
08 と 09 は,Tcl では正しい 8 進数ではなかったためです.
幾つかの解がありえます.
George A. Howlett によれば,
set wknum [format "%g" [exec date +%W]]
set index [expr [exec $wknum%[llength $pop_server_list]]
Fred Feirtag の解は,
set index [expr (1[exec date +%W]-100)%[llength $pop_server_list]]
Dan R. Schenck からは,
set index [expr [string trimleft [exec date +%W] 0]%[llength $pop_server_list]]
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9L. 拡張 Tcl や Expect を使っているならば,コマンドライン上で指定さ
れたパラメータを,リスト形式の Tcl 変数 argv で参照することができます.
拡張 Tcl の場合は,プログラム名は Tcl 変数 programName に格納され,
argv[0] には入らないので注意が必要です.
[email protected] (Brad Morrison) と [email protected] (Bud Bach) の
回答に感謝します.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9M. コメントは,置きたい所にそのまま置くことはできません.そうしたい
場合は,コメントを "{" の内側に移動しましょう.例えば,次のように書き
ます.
case 1 {
-1 {
#
# 情報が見付けられない場合
#
exit 2
}
0 {
#
# 引数にエラーがある場合
#
exit 1
}
default {
#
# 望む情報が見付けられた場合
#
exit 0
}
}
[email protected] (Gerald W. Lester) に感謝.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9N. 拡張 Tcl では,次のように,これを安全に行えます.
set infp [open "|compress -dc $fileName"]
set outfp [open "|gzip -c $newFileName" w]
copyfile $infp $outfp
コードの例を提供してくれた [email protected] (Karl Lehenbauer) に感謝.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9O. 拡張 Tcl は,たくさんのこの手の機能を提供しています.例えば,拡張
Tcl には 'signal' コマンド:
signal action siglist [command]
ここで action は,"default", "ignore", "error", "trap", "get",
に加えて POSIX の "block" と "unblock" アクションのいずれか
(もちろん,POSIX システムでのみ有効).siglist は,記号表現,あ
るいは,数値表現の Unix シグナルのリスト (前置記法 SIG はオプ
ション). command は,定義するエラー・ハンドラ (あるいは,単に,
{puts stdout "Don't press *that* key!"} :-).
"trap" は期待通り動きますし,"error" と "get" は,キーボード・トラバー
サルを要求する会話的プログラムでは,極めて便利です.
拡張 Tcl は,fork の様な機能も持っています.
回答は [email protected] (Brad Morrison) から寄せられました.
------------------------------
-X- How, in Tcl, can I XXX:
この問題点を扱った長文の記事が,以下で得られます.
ftp://harbor.ecn.purdue.edu/pub/tcl/docs/README.programmer
ここに掲載するのは,短い答えです:
Q. 後になって実行するコマンドを組み立てようとしてるのですが,空白や
特殊文字を含む変数で問題が出てしまいます.
A. コマンドを組み立てる最も安全な方法は,list コマンドを使うことです.
そうすれば,リスト構造を壊さずにすみます.余計なエバリュエータで終って
しまうこともあるので,ダブルクォートの使用は避けましょう.例題として,
クリックしたら,その上のラベルを出力するボタンを生成するプログラムを示
します.
間違えた答え #1:
button $myname -text $label -command "puts stdout $label"
なぜ? それは,もし $label が空白文字を含むなら, puts コマンドに
間違えた数の引数が渡されてしまうから.$label が $ や [ ] 文字
を含むなら,出力されずに評価されてしまいます.
良い答え #2:
button $myname -text $label -command [list puts stdout $label]
なぜ? list が $label の値を適切にクォートするからです.
Q. 後になって実行するコマンドを組み立てようとしてるのですが,変数が組
み立て時に評価されてしまったり,コマンドの実行時に評価されてしまったり
して,思い通りに動いてくれません.
A. これを行う,最も明晰な方法は,実行時の変数の使用を隠蔽するようにプ
ロシージャを定義することです.そして,前に述べた様に list コマンドを用
いてプロシージャの呼び出しを組み立てあげます.(実行中でさえ,プロシー
ジャの定義は可能です.別のプロシージャの内部で生成されても,それはグロー
バルなスコープを持ちます.)
間違えた答え #1:
button $myname -text $label -command \
[list puts stdout $ArrayOfDynamicStuff($label)]
なぜ? 配列変数は,ボタンが生成された時の値で置き換えられてしまい,
ボタンがクリックされた時の値とはならないから.また,コマンドが
グローバルなスコープで実行されることにも注意しなければなりませ
ん.そのため,"global ArrayOfDynamicStuff" をコマンドの中に含
める必要はありません.
間違えた答え #2 (バッククォートと list):
button $myname -text $label -command \
[list puts stdout \$ArrayOfDynamicStuff($label)]
なぜ? これでは,list コマンドと $ のバッククォートが,互いに喧嘩
してしまいます.結果として全体の振舞いは,以下の様になり,
puts stdout {$ArrayOfDynamicStuff(foo)}
配列要素の値に対する置換が働かなくなってしまいます.
いかがわしい答え #3 (バッククォートとダブルクォート):
button $myname -text $label -command \
"puts stdout \$ArrayOfDynamicStuff($label)"
なぜ? これは,$label の値が,特殊文字や空白文字を含まない時だけ,
まともに動きます.
完全な答え #4 (proc):
proc doit { i } {
global ArrayOfDynamicStuff
puts stdout $ArrayOfDynamicStuff($i)
}
button $myname -text $label -command [list doit $label]
なぜ? ボタンのために簡単な Tcl プロシージャを作ってやる様にしてお
けば,ちゃんと動作してくれます.何故なら,凝ったクォーティング
をする必要をなくしてくれますし,ボタンから起動される処理の仕様
変更も,容易になります.
Q. プロシージャに,可変個数の引数を渡そうとしてるのですが,$args を正
しく展開するところで,つまってしまいます.
A. eval と ダブルクォートを組み合わせて使おうとするのは,止めましょう.
なぜなら,そうすると,余計な評価が起動されてしまうからです.eval コマ
ンドは,その引数が 1 つ以上の場合は,それらを 1 つに連結します.そのた
め,ダブルクォートで 1 つに括ってやる必要が,まったく無くなります.
前述の button の例を拡張して見ましょう.
間違えた答え #1:
proc mybutton { myname label args } {
button $myname -text $label -command [list puts stdout $label] $args
}
なぜ? 変数 $args に格納されている mybutton への全ての追加引数は,
1 つのリスト要素にグループ化されてしまっています.しかしながら,
button コマンドはその引数に,サブリストではなく,個々の引数を
要求するからです.
間違えた答え #2:
proc mybutton { myname label args } {
eval "button $myname -text $label -command [list puts stdout $label] $args"
}
なぜ? ダブルクォートは,$args と同じように,$label の展開を可能に
します.そのため,$label の値に空白文字が含まれるなら,button
コマンドには,正しくない引数並びが渡されることになってしまいま
す.
良い答え #3:
proc mybutton { myname label args } {
set cmd {button $myname -text $label -command [list puts stdout $label]}
eval $cmd $args
}
なぜ? eval は,最初に 2 つの引数を連結して,次にその結果をインタ
プリタを介して実行します.これは,$cmd や $args から,外側のカ
リー括弧を外して,2 つの変数の全ての要素を 1 つのリストにする
と考えられます.$label は,1 回しか評価されません.そして,put
コマンドも正しく動きます.さらに,args が入れられる度にも,1回
しか処理しません.
Q. なんで if/while/for 文で,文法エラーになってしまうのでしょう.
A. ひょっとして,
wish: set foo bar
wish: if {$foo == bar} {puts stdout bar}
syntax error in expression "$foo == bar"
の様に書いてはいないでしょうか.これでは,文字列としても変数としても評
価されません.式中のオペランドとしての文字列は,ダブルクォートか中括弧
で括ってやらねばなりません.
wish: if {$foo == "bar"} {puts stdout bar}
や
wish: if {$foo == {bar}} {puts stdout bar}
の様に書き換えましょう.どちらを選ぶかは,展開させたいかどうかで決めて
下さい.
この記述は,"Jesper Blommaskog" からのコン
トリビュートです.
------------------------------
-X- Tcl で XXX するには,どうしたらいいの?
A9Q. 明示的にファイルを source するのではなく,Tcl ライブラリを作るよ
うにしましょう.
Step 1. ファイルを共有ディレクトリに置きます.
Step 2. "ライブラリ" のための,tclIndex を作ります.私は Makefile 中
に,次のように書いています.
install.index:
(cd ${DESTDIR}/tclscripts/lib; \
echo 'source /usr/local/lib/tcl/init.tcl;\
auto_mkindex . *.tk' | tcl ; exit 0)
Step 3. 作成した Tcl スクリプトに,ライブラリを参照させるようにします.
例えば,以下のようにします.
# local additions
lappend auto_path /usr/local/lib/tcl_local $env(RDS_TCL_SCRIPTS)/lib
このようにすれば,スクリプトはプロシージャを,ライブラリの中から参照し
ようとし,"unknown" コマンドが,自動的にプロシージャを読み込んでくれま
す.
この記述は, Joe VanAndel からのコントリビュー
トです.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9R. なんで
linsert $list 0 ..
と実行したのに,結果に .. が挿入されていないのか,と良く聞かれます.
[email protected] (Jesper Blommaskog) が,以下のように答えてい
ます.
lappend 以外のリスト操作では,戻り値を保存しなければなりません.これは,
list, lindex, lrange, lreplace に当てはまります.
これは,ひょっとしたらやりたかった事が正しく動く例です.
set list [ linsert $list 0 .. ]
------------------------------
-X- Tcl で XXX するには,どうしたらいいの?
A9S. Frank Smith によると,拡張 Tcl
を持っているなら,
read $fileId [fstat $fileId size]
のようにして実現可能です.これは,'fileId' から,その時点で読み込める
だけのバイト数だけ読み込み,結果としてブロック化しません.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9T. 標準入出力パッケージは,文字をバッファリングする事で,速度面を最
適化しています.そのため,不必要なシステムコールをしなくて済みます.こ
れは,会話的な使用には不適切ですので,標準入出力はその振舞いを,ファイ
ルが端末である場合には変更します.パイプに書き込む時には,端末に書き込
んでいる訳ではないので,書き込んだ出力はバッファリングされてしまいます.
同様に,パイプの向こうにある他のプログラムがその応答を出力する時にも,
バッファリングされてしまいます.結果として,パイプの両端のプログラムは,
互いに入力を待って,立往生してしまいます.これを解決するには,Tcl では
flush コマンド,C では fflush() を使ってパイプをフラッシュすることです.
もっとも,しばしば,パイプラインの端のプログラムの制御が出来ない場合も
あります.その様な場合は,解決する唯一の解は,仮想端末 (pty) を使う事
です.が,これは結構,簡単ではありません.
これは,標準の Tcl ではサポートされていませんが,expect では,spawn コ
マンドで pty を開き,コマンドを起動してくれます.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9U. だれも答えてくれる人はいない様ですが,大丈夫.Tcl 自身が,そのバー
ジョンを答えてくれます.以下のように打ち込んで見ましょう.
info tclversion
また,Tk のバージョンは,以下のようにして知ることが出来ます.
puts $tk_version
その他の拡張では,他の手段があるでしょう.
------------------------------
-IX- Tcl で XXX するには,どうしたらいいの?
A9V. Earle Lowe は,次のように答えてます:
> TCL/Tk が存在していてもいなくても関係なく動作できるスタンドアローン
> のプログラムを作りたいならば,もう少し作業する必要があります.
>
> 基本的には,これは,TCL 初期化ファイルを C 文字列に変換し,
> Tcl_Init() や Tk_Init() を呼ぶのではなく,変換された C 文字列を引数
> に Tcl_Eval() を呼ぶ必要があります.
>
> wish_compiler パッケージ(Alexei Rodriguez 作)を
>
ftp://harbour.ecn.purdue.edu/pub/tcl/code/wish_compiler.shar.gz
>
> から,拾って来るとよいでしょう.
> このパッケージには tcl2c コンバータが入っていて,その使用法もついて
> 来ます.
>
> Makefile のちょっとした技を使えば,TCL/Tk の目的通りの使用 (様々な種
> 類の wish を用いた,インタプリタ型言語としての使用) 方で用い,コード
> を実行させる時には,コンパイルされたスタンドアローンプログラムを生成
> することも可能です.
------------------------------
-X- Tcl で XXX するには,どうしたらいいの?
A9W. Eric Bleeker が書く所によれ
ば:
ひょっとしたら,こんな風に書いていませんか:
% set foo "bar baz"
bar baz
% foreach aap $foo {
set $aap(1) "something"
}
can't read "aap(1)": variable isn't array
これは,Tcl が配列要素 "aap(1)"を,存在してもいないのに,置換しようと
しているのです.これを解決するには,以下のようにします.
% foreach aap $foo {
set [set aap](1) "something"
}
この場合は,2 つの配列 "bar" と "baz" は,生成されます.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.A.1. ほとんどのシステムでは,インタプリタはフルパスで指定する必要
があります.従って,wish スクリプトの冒頭を,次の様に始めてはいけませ
ん.
#! wish -f
その上,多くの Unix システムでは, #! 行に書ける文字列長の最大長さに制
限があります.もし制限を越えてしまうと,期待通りの動作はしないでしょう.
ですから,wish のコードでは,次のようにしてもいけません.
#! /長いプロジェクト名/何か/長〜い/パス名/bin/sun4/wish -f
行は短めにしておきましょう.32 文字以下を推奨します.
最後に付け加えると,幾つかのマシンでは,-f の後に空白文字が入ると問題
となる事があります.-f は,ファイルの最初の行の最後の文字であるように
注意しましょう.
ちょうど議論されていた,もう 1 つの技として,シェル・ファイルの 1 行目
を次のように書く,というものがあります.
/usr/ucb/tail +2 $0 | /usr/local/bin/dpwish -notk $* ; exit
ここで,/usr/local/bin/dpwish は,一般には別のパス名に書き換える必要が
あるかもしれません.
別の技が提案されています (Eric Schenk があみだしたものです).
#!/usr/local/bin/wish -f
# The next line is a comment in Tcl, but not sh \
exec /usr/local/bin/wish $0 -f ${1+"$@"}
他のユーザは,ウィジェットの表示されていない空の wish ウィンドウが出る
と言うような症状を報告しています.これは,インタプリタのパスが長過ぎる
ためです.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.A.2. Tk は,8 bit 未満のカラー・スクリーンでは綺麗に動きません.も
し,そんな環境で動作させようとするならば,Tk/wish のソースの中の,ビッ
ト・プレーンの数を調べるために呼び出されている全ての
DefaultDepthOfScreen 関数の記述されている場所を探しだします.そして,
1 bit プレーンである振りをするよう書き換えるか,あるいは,Tcl 変数を監
視するプロシージャを呼び出すように書き換えます.この方が,つぶしが効き
ますし,好ましいでしょう.
別の選択しとして,使用しているサーバに,スタティク・カラーのような,別
のビジュアル/カラーモデルが使えないか,調べて見る手があります.この様
なモデルの 1 つは,Tk をよりよく動かす事が出来るでしょう.
この情報を提供してくれた "Nathaniel Borenstein"
に感謝します.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.A.3. option コマンドのドキュメントを読みましょう.
そうしたならば,次のようにして実現すればよいことが分かる筈です.なお,
ここではプログラム名を xwf とします.
次に示す 2 つの汎用プロシージャを,ライブラリに置きます.
# envVal envValName
# 環境変数 envValName を見付けだし,その値を返す.存在しない場合は
# {} を返す.
proc envVal {envValName} {
global env
if [info exists env($envValName)] {return $env($envValName)} {return {}}
}
# loadAppDefaults classNameList ?priority?
# 指定したクラス名 className に一致する app-defaults ファイルを
# X ツールキット・イントリンシクス に指定された順番で探しだし,指定
# されたプライオリティ (デフォルトは startupFile) でロードする.
proc loadAppDefaults {classNameList {priority startupFile}} {
set filepath "[split [envVal XUSERFILESEARCHPATH] :] \
[envVal XAPPLRESDIR] \
[split [envVal XFILESEARCHPATH] :] \
/usr/lib/X11"
foreach i $classNameList {
foreach j $filepath {
if {[file exists $j/$i]} {
option readfile $j/$i $priority; break
}
}
}
}
# そうしたならば,例えば,次のように xwf のコード中に記述します.
option add Tk.BoldFont "*-lucida sans-Bold-R-Normal-*-100-*" widgetDefault
loadAppDefaults {xwf XWF} userDefault
これは,プログラムのデフォルトをまず設定しています.そして,ユーザのデ
フォルトのリソース値に指定されたデフォルト値を読み込み,最後に,サイト
毎,あるいは,一般的な app-defaults リソースを読み込みます.
勿論,実行時にユーザがこれらの値を設定しなおすことが出来るようなプログ
ラムを,xwf に組み込んでやる事も可能でしょう.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.A.4. 1992 年 6 月現在のところ,未拡張の Tk では,これは不可能です.
これは,パターンが 16 進の内部コードとして提供されているためです.外部
ファイルを指定するしかありません.一方,この様な機能を提供している拡張
を使う手もあります (BLT は,その 1 つです).
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.A.5. Tk は,今の所 Xt ツールキットを使っていません.そのため,
libXm.a のルーチンによる厳密な Motif への忠実性を提供する事は出来ませ
ん.しかしながら,Tk の作者は,Motif のユーザインタフェースの形式を採
用していますので,Tk で,Motiof の様なインタフェースを実装しようとする
のは簡単であることが分かるでしょう.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.A.6. 残念ながら,Tk は現在の所,Xview ベースや Xt ベースのウィジェッ
トをユーザインタフェースに用いていません.従って,OpenLook に準拠した
(あるいは,似通った) インタフェースを扱う事は,当面は非常に難しいでしょ
う.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.A.7. 同じ原因に根がある問題として,「Tk 3.3 の send がこけるので
すが」とか,「xauth は,どうやって使うのですか」などといった質問があり
ます.
Tk 3.3 では,X11 の xauth セキュリティ機構が使われています.これは,よ
り安全な環境を提供してくれますが,ユーザに,通常よりは多い設定を要求し
ます.ユーザは,Xauthority ファイル (通常は $HOME/.Xauthority) を生成
しなければならず,また,X サーバを -auth オプションに,生成した
Xauthority ファイルのファイル名を付けて起動する必要があります.
xauth や,相当するソフトウェアの使い方,設定ファイルの記述法に関する詳
細は,使用しているシステムの X11 ドキュメントを参照して下さい.
xauth の入門の文章は,以下から入手可能です.
ftp://harbor.ecn.purdue.edu/pub/tcl/docs/Xauthority
ファイル tk3.3/Makefile.in を,以下のようにコメントアウトすることで,
Tk を xauth によらず,動作させる事も可能です.
# To turn off the security checks that disallow incoming sends when
# the X server appears to be insecure, reverse the comments on the
# following lines:
#SECURITY_FLAGS =
SECURITY_FLAGS = -DTK_NO_SECURITY
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.A.8. 最近,いくつかの簡単な例題が,comp.lang.tcl に投稿されまし
た.Eric Bleeker は,慈悲深くも
彼のパッケージを以下に公開してくれています.
ftp://harbor.ecn.purdue.edu/pub/tcl/code/tkHelloWorld*
このプログラムは,既に Tcl や Tk ライブラリ,ヘッダファイルなどがイン
ストール済であることを前提としています.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.B.1. Tk ウィジェットに対する,全てのクラスバインドは,
$tk_library/tk.tcl で初期化されます.このファイルを,独自のバインドをイン
プリメントする際の参照にすると良いでしょう.例えば,次のコードは,全て
のリストボックスに対して,マウスボタン 1 で提供されるドラッグ-選択機能
を,マウスボタン 3 でも提供するようにするものです.
bind Listbox <3> {%W select from [%W nearest %y]}
bind Listbox {%W select to [%W nearest %y]}
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.B.2. "bind" を,空文字列のコマンド名を引数に実行します.例えば,エ
ントリ・ウィジェットで Delete キーを無効にするには,以下のようにします.
bind Entry {}
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.B.3. 1992 年 6 月現在,これを行うのは Tk にとって安全ではありませ
ん.これは,John Ousterhout によってバグリストに加えられており,将来の
バージョンでは修正される予定です.
現在でも行い得るこの問題の解は,バインド自身を変更するのではなく,そこで束
縛されているコマンドの方を変更してしまうものです.例えば,バインドしたプロ
シージャが実行すべき機能を示す状態変数を保持しておき,プロシージャが束
縛から実行される際に,必ず渡す様にしておきます.そうしてやって,プロシー
ジャ内で実行すべきコードを,変数の値によって切替えてやります.あるいは,
バインドするコマンドを,単に "eval $cmd" の様にしておき,変数 "cmd" の内容
を,アプリケーションの状態によって切替えてやる事もできます.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.B.4. それを指定するには, ではなく, などとしなければな
りません.X11 環境下では,キーは,その keysym で指定されます.ユーザは,
xmodmap -pk コマンドか,xev コマンドを使う事で,現在の設定下でキーボー
ド上のキーに割り付けられている keysym の値がどんなものであるかを知る事
ができます.
keysym が,Tk にとって,その使用法が知られていないものであった場合,ファ
イル ks_names.h を修正する事で,対応させることもできます.この対応法で
注意しなければならないことは,他人は同様の修正をしているわけではない,
という点です.しかしながら,これが新しい keysym を受け入れさせる唯一の
方法です.
この注釈を寄せてくれた Wayne Christopher に
感謝します.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.B.5. mwm の様ないくつかのウィンドウマネージャでは,Tk で問題となる
ようなマウスのバインドを定義し得ます.使用中のウィンドウマネージャの初期化
ファイル (例えば ~/.mwmrc など) を保存しておいて,動いている人のそれを
コピーして見ましょう.この非常に貴重な情報を寄せてくれた
[email protected] (Brad Morrison) に感謝します.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.B.6. 実際に問われた質問は,以下の通り.
>どんなキー入力に対しても,ウィンドウのタイトルバーを更新するように,
>テキスト・ウィジェットをバインドしようとして,次のように書いて見ました.
>
> text .textWin ...
> bind .textWin {+wm title . "Nextedit - edited"}
>
>これは,ウィンドウの中のテキストが編集済であるかどうかを,ユーザに
>知らせる機能をサポートします.問題は "+" です.これは,どこに行く
>んでしょう? 色々な書き方を試して見ましたが,パーズ・エラーに終る
>か,wm コマンドが完全にバインドを乗っ取ってしまい,テキストに何の入力
>もできなくなるかになってしまいます.キー入力をテキストに入力させ,
>*かつ*タイトルバーを更新させるには,別のバインドを付け加える必要があ
>ると思うのですが,どうすればよいのでしょう?
>
[email protected] (Gerald W. Lester) が,答えました:
クラス指定のバインドを,ウィジェット指定のバインドに降ろす必要があります.
こうしてみて下さい.
bind .textWin Text
bind .textWin {+wm title . "Nextedit - edited"}
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.C.1. Tk2.1 と Xt は,異なった X との接続をしており,XtAppNextEvent
は,X との接続から (Tk に) 何も行かない様にブロックしてしまいます.こ
れを修正する 1 つの方法は,
ConnectionNumber(Tk_Display(tk_window));
を使って,Tk の接続ナンバを得て,XtAddInput を使って,これを Xt のイベ
ントハンドラとして記憶させることです.XtAddInput のコールバック関数は,
Tk_OneEvent(1) を実行するプロシージャをラップします.Xt に記憶されてい
ない Tk のファイルを読み込むことは,問題となるかも知れません.
この情報を寄せてくれた [email protected] (Joe Wang) に感謝します.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.C.2. [email protected] (M. G. Christenson) が紹介してくれたやり方を,以
下に示します.
利用可能なカーソル名の一覧を調べるために,
/usr/include/X11/cursorfont.h を参照します.カーソル名は,この中の記述
から,頭の 'XC_' を取り去ったものです.
以下に示すのは,私のアプリケーションで,何か動作中にカーソルの形状を変
える 'busy' プロシージャです.実行したいコマンドを引数にこれを呼ぶだけで,
コマンドの実行が完了するまで,カーソルを時計マークに変更してくれます.
(これを実行した後に生成される) 新しいウィンドウの中では,カーソルは通
常の形状となる点は注意して下さい.
proc busy {cmds} {
global errorInfo
set busy {.app .root}
set list [winfo children .]
while {$list != ""} {
set next {}
foreach w $list {
set class [winfo class $w]
set cursor [lindex [$w config -cursor] 4]
if {[winfo toplevel $w] == $w || $cursor != ""} {
lappend busy [list $w $cursor]
}
set next [concat $next [winfo children $w]]
}
set list $next
}
foreach w $busy {
catch {[lindex $w 0] config -cursor watch}
}
update idletasks
set error [catch {uplevel eval [list $cmds]} result]
set ei $errorInfo
foreach w $busy {
catch {[lindex $w 0] config -cursor [lindex $w 1]}
}
if $error {
error $result $ei
} else {
return $result
}
}
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.C.3. これは,将来解決すべき (ほとんど無限の) リスト中にある事柄で
す.
もし時間があるならば,これを解決するコードを書いて見て下さい.非常に歓
迎されるでしょう.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.C.4. "wm deiconify " を使いましょう.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.C.5. [email protected] (Wayne A. Christopher) によれば:
Tk で,トップレベルウィンドウを生成し,それをマップせずに (wm
withdraw) おきます.そうしておいて,他のウィンドウのサブウィンドウにな
るように,そのウィンドウの親を付け変えてからマップしてやります.
Tk アプリケーションが別プロセスであったとき,これを行って見ました.でも,
同じプロセスであったならば,各々のツールキットが制御を獲得しようとして,
イベントループで問題が起きるでしょう.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.C.6. John Ousterhout ([email protected]) によれば:
と イベントは,"%d" を使ってアクセス出来る,「詳細」
フィールドを持っています.そのフィールドが "NotifyInferior" であるなら
ば,マウスポインタが子ウィンドウを出入りすることを意味します (実際,イ
ベントを受け取るウィンドウの領域に留まります).スクリプトの中で詳細フィー
ルドをチェックできるようにすべきで,値が NotifyInferior ならばイベント
を無視してやります.詳細フィールドの完全な情報と Enter/Leave イベント
については,Xlib のドキュメントを参照して下さい.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.C.7.
[YIP Chi Lap [Beta] によれば]
Tk と Xt のウィンドウの間で直接インタラクションする (例えば,
Xt でディスパッチされたルーチンで Tk のウィンドウを描画するとか) 様な
ものではありませんが,両者がとりあえず動作する,重たいイベントループの
ルーチンを (今まで) 書いてました.
XEvent xevent;
for (;;)
{
if (XtAppPending(appcontext))
{
XtAppNextEvent(appcontext,&xevent);
XtDispatchEvent(&xevent);
}
Tk_DoOneEvent(TK_DONT_WAIT);
}
[David C Mudie によれば]
私達は,後に示すメインのイベントループを使っています.基本的な
アイディアは,Xt のサーバ・コネクションと Tk のサーバコネクション両方
から来るイベントを監視し,(イベントが来たならば) ライブラリのディスパッ
チャを呼ぶと言うものです.
次に示すコードの断片は,使用に当たっては,きちんと書き直してや
る必要があります.インクルードファイルの指定や,グローバル変数の宣言は
欠けています.
/* Allow Tcl/Tk and Xt to work at the same time. */
void tkGo(void)
{
extern Widget topLevel;
int width = ulimit(4, -1);
fd_set readfds;
struct timeval timeout;
int nfds;
int tkfd = ConnectionNumber(Tk_Display(mainWindow));
int xtfd = ConnectionNumber(XtDisplay(topLevel));
Tcl_VarEval(interp, "update", NULL);
while (1) {
/* Select on X server connections to wait for event. */
/* Timeout every half second to allow processing of non-X events */
FD_ZERO(&readfds);
FD_SET(tkfd, &readfds);
FD_SET(xtfd, &readfds);
timeout.tv_sec = 0;
timeout.tv_usec = 500000;
nfds = select(width, &readfds, NULL, NULL, &timeout);
if (nfds < 0 && errno != EINTR) {
perror("select");
} else if (nfds == 0) {
/* printf("timeout\n"); */
}
while (XtPending()) {
XtProcessEvent(XtIMAll);
}
while (Tk_DoOneEvent(1)) {
/* do nothing */
}
if (mainWindow == NULL) {
// Tcl_DeleteInterp(interp);
// Tcl_DStringFree(&command);
Tcl_Eval(interp, "exit");
return;
}
}
}
[Davide Frisoni によれば]
異なったアプリケーション間の通信に,Xt のプロパティを用いるこ
とも出来るでしょう.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.C.8. [email protected] (Martijn Figee Huffi Marcel Huefken)
が言うには:
: bind .frame {puts stdout "resise\n"}
: で,.frame がリサイズできず,標準出力に "resize" も出力されない,と
: いう問題を抱えてしまってるのですが.
以下のやりかた
bind .frame {puts...}
を,試して下さい.動くはずです.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.D.1. 一般的な作法として,wm min/maxsize を使いましょう.以下に示す
のは,サイズ変更可能なリストボックスです.
#!/usr/local/bin/wish -f
wm minsize . 20 20
wm maxsize . 1152 900
pack append . [listbox .l -borderwidth 2 -relief raised] {expand fill}
テキストウィジェットで,きちんとサイズ変更を管理するにも,同じ方法が用
いられます.
"John C Ellson"
-X- Tk で XXX するには,どうしたらいいの?
A10.D.2. Tk で,隣り合わないエントリを選択可能に変更する方法は,Marc
R. Ewing の Listbox.patch を参照して下さい.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.D.3. Tk のリストボックスのデフォルトでは,その選択物を X のセレク
ションとして外部に参照可能としています.これは,同時に 1 つしか,行え
ません.
Tk の,この仕様を変更するには,リストボックスを生成する時に,
-exportselection false を指定してやります.あるいは,コマンド
option add *Listbox.exportselection false
を,スクリプトの最初に書いてやります.
この話題を提供してくれた David Herron に感謝.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.D.4. まず,問題を明確にして見ましょう.問題は,リサイズ可能なリス
トボックスを作りたいが,最小サイズの設定によって制約を掛けたくない,と
いうものです.それゆえ,リストボックスが上下に広がる (fill expand) 様
にパックしてやり,グリッドを設定して (その結果,ウィンドウのリサイズは
行単位となります),1x1 の初期ジオメトリでデフォルトを上書きしてやりま
す.この様に (次のコードを,実例として実行し,リサイズして見て下さい)
して,問題を解決しようとしたのですが ....
listbox .l -geom 1x1 -setgrid 1 -yscrollcommand ".s set" -relief sunken -bd 2
scrollbar .s -command ".l yview"
pack .s -side right -fill y
pack .l -side top -fill both -expand 1
.l insert end one two three four five six seven eight nine ten "THE END"
リストボックスに,表示仕切れないアイテムが存在する場合には,底辺に半行
のすき間が出来てしまいます.これは,ユーザがそこに何が表示されているの
かと混乱させる元になってしまいます.なんで,こうなるのでしょう?
以下が,その答えです.
リサイズの前の,ウィンドウが生成されるところを見て見ましょう.
小さなかわいらしいスクロールバーが,押し縮まって極小のウィンドウに表示
されるのがわかるでしょう.これもまた,最小サイズを要求し,そうしてから,
リストボックスのジオメトリの指定の,開始で底辺までの利用できる空間が受
け取られます.その結果,リサイズが文字単位に制約されるまでは,無くなり
ません.
やることは,実際に表示される行と列数で,ウィジェットの -setgrid 指定を
行うことです.上の例では,-geom 1x2 に設定すると,うまく誤魔化せます.
この情報を提供してくれた Frank Stajano に感謝.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.E.1. 最新の Tk のキャンバスには,その内容を記述したファイルを生成
できる,save サブオプションが付いています.デフォルトでは出力は,カプ
セル化 PostScript ですが, xpm3 で出力することも出来ます.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.E.2. いいえ.何らかの線で囲まれた領域を塗りつぶしたいならば,結局,
ポリゴンを使うしかありません.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.E.3. まだ,不可能です.
"Jesper Blommaskog" .
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.E.4. Nathaniel Pryce によれば:
> 論理的に埋め尽くすように描画されたオブジェクトのあるキャンバス (謂わ
> ば,チェス盤や,世界地図みたいなものです) のあるウィンドウを作りまし
> た.このトップレベルウィンドウをリサイズ可能にしたいのですが,勿論,
> リサイズした時にはキャンバス内のオブジェクトを,リサイズされた大きさ
> に従って大きさを変更させてやりたいのです.今のところ,オブジェクトの
> サイズ変更自体はできますが,その処理をいつ起動するかのタイミングを検
> 出することが出来ずに困っています.ウィンドウがリサイズされた時のノー
> ティファイは,どの様に得ればよいのでしょうか?
Nat の答えは:
コマンドを Configure イベントにバインドする必要があります.例えば,次のよ
うに,
proc config {w h} {
puts stdout ".canvas - width = $w, height = $h"
}
bind .canvas "config %w %h"
.canvas - width = 224, height = 251
.canvas - width = 224, height = 151
.canvas - width = 224, height = 243
# and so forth
すればよいでしょう.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.E.5. "David Herron" によれば:
スクロールコマンドのハンドラを書き換えてやる必要があります.
`scrollbar' コマンド (と,`listbox' コマンドも) のマン・ページを,まず
読みましょう.すると,scrollbar コマンドで実行される様に,次のようにそ
の scrollcommand に追加すればよいことが分かるでしょう.
.f.c yview; .f.lb yview
最後に,私の最終的なものを付け加えておきます.このコードは,スクロール
が「右にならえ」である点が優れています.
listbox .l1 -relief sunken -yscrollcommand {
scrollMultiple_y { .l1 .l2 .l3 } .vs
}
listbox .l2 -relief sunken -yscrollcommand {
scrollMultiple_y { .l1 .l2 .l3 } .vs
}
listbox .l3 -relief sunken -yscrollcommand {
scrollMultiple_y { .l1 .l2 .l3 } .vs
}
scrollbar .vs -relief sunken -orient vertical \
-command {setMultiple_y {.l1 .l2 .l3}}
bind .l1 <1> {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
bind .l1 {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
bind .l1 {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
bind .l1 {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
bind .l2 <1> {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
bind .l2 {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
bind .l2 {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
bind .l2 {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
bind .l3 <1> {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
bind .l3 {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
bind .l3 {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
bind .l3 {
selectMultiple {.l1 .l2 .l3} [%W nearest %y]
}
proc scrollMultiple_y {lists vs total window first last} {
if {[expr $first+$window] > $total} {
set first [expr $total-$window]
set last [expr $first+$window]
}
setMultiple_y $lists $first
$vs set $total $window $first $last
}
proc setMultiple_y {lists index} {
foreach l $lists { $l yview $index }
}
proc selectMultiple {lists index} {
foreach l $lists { $l select from $index }
}
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.F.1. [email protected] (George A. Howlett) は,winfo のマニュ
アルを指摘しています.winfo name . で,現在のアプリケーションの名前を
得ることが出来ます.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.F.2. Owen Rees によれば,
「ボーダーの幅を 0 でなくする必要がある」ということです.これには,次
のようにします.
text .t -width 20 -height 20 -relief sunken -borderwidth 4
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.F.3. これを行う方法は,少なくとも 2 つ,あります.1 つは,Tcl ユー
ザ寄贈コード・アーカイブから得られる,ハイパーテキスト・ウィジェットを
使う方法です.実際にどこから得られるかは,"tcl-faq/part4" や
"tcl-faq/part5" を参照して下さい.
そして,次に示すコードは,"Michael Moore"
から寄せられた,Tk のみでこれを行う
方法です.
#! /bin/wish -f
#
# This demonstrates how to create a scrollable canvas with multiple
# buttons.
#
# Author : Michael Moore
# Date : November 17, 1992
#
#
# This procedure obtains all the items with the tag "active"
# and prints out their ids.
proc multi_action {} {
set list [.frame.canvas find withtag "active"]
puts stdout "Active Item Ids : "
foreach item $list {
puts stdout $item
}
}
#
# This simulates the toggling of a command button...
# Note that it only works on a color display as is right now
# but the principle is the same for b&w screens.
#
proc multi_activate {num id} {
set tags [.frame.canvas gettags $id]
if {[lsearch $tags "active"] != -1} {
.frame.canvas dtag $id "active"
.frame.canvas.button$num configure \
-background "#060" \
-activebackground "#080"
} else {
.frame.canvas addtag "active" withtag $id
.frame.canvas.button$num configure \
-background "#600" \
-activebackground "#800"
}
}
proc setup {} {
frame .frame
scrollbar .frame.scroll \
-command ".frame.canvas yview" \
-relief raised
canvas .frame.canvas \
-yscroll ".frame.scroll set" \
-scrollregion {0 0 0 650} \
-relief raised \
-confine false \
-scrollincrement 25
pack append .frame \
.frame.scroll {left frame center filly} \
.frame.canvas {left frame center fillx filly}
pack append .\
.frame {left frame center fillx filly}
button .frame.canvas.action \
-relief raised \
-text "Action" \
-command "multi_action"
.frame.canvas create window 1 25 \
-anchor w \
-window .frame.canvas.action
for {set i 2} {$i < 26} {incr i} {
button .frame.canvas.button$i \
-relief raised \
-background "#060" \
-foreground wheat \
-activebackground "#080" \
-activeforeground wheat \
-text "Button $i"
set id [.frame.canvas create window 1 [expr $i*25] \
-anchor w \
-window .frame.canvas.button$i]
.frame.canvas.button$i configure \
-command "multi_activate $i $id"
}
}
setup
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.F.4. Spencer W. Thomas によれば,次のよう
にする必要があるそうです.
wm minsize . 0 0
text .text
pack append . .text {fill expand}
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.F.5. 最近の Tk では大部変更があって,大文字ではじまる名前はクラス
名として受け取られるようになりました.ウィジェットのインスタンスを指定
するには,小文字で始めなければなりません.これは,X11 のリソース定義で,
クラスとインスタンスを区別する事を可能にしてくれます.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.F.6. 最近, Micael Salmon が投稿した内容
によると:
記事 <[email protected]>で, 私の書いたことによると:
|> 私は現在,もう 1 つの tn3270 端末を開発してるのですが,同じサイズの
|> ボタンを生成するところで躓いてます.PF とカーソルキーのためにボタン
|> の配列を生成したのですが,それらを,みんな同じ大きさにしたいのです.
|> それらを一列に配置する事は問題ではありませんでした.が,それらにビッ
|> トマップを表示させると,水平位置がずれてしまうのです.ボタンの,水
|> 平・垂直サイズを winfo で読み取り,それらの最大サイズにあわせてサイ
|> ズを統一するよう pad を入れたのですが,どうもうまく動きません.
|> ビットマップとテキストを混用して,テキストボタンでピクセル単位にサ
|> イズ指定するのに,水平・垂直サイズをプリセットする技はうまくない様
|> です.どなたか助言頂けませんか?
Jim Wight は,reqheight と reqwidth を用い,
各ボタンの pack コマンドで padx と pady を指定する事を助言しました.
Jim の言うには:
私がこのグループに投稿した,最初の回答の試みに欠けてるものを補うにはど
うしたらいいかという記事に対して,reqwidth と reqheight を使うようにと
答えてくれた Tuomas Tuomas J Lukka の回答が
いいと思います.
余計な話は抜きにして,私が Michael にメールした,最終版の解決法を,以
下に示します.
frame .frame1
frame .frame2
button .frame1.a -text "pretty long button text"
button .frame1.b -text "short one"
button .frame2.c -bitmap "@/usr/include/X11/bitmaps/xlogo32"
button .frame2.d -text "tiny"
set long [winfo reqwidth .frame1.a]
set short [winfo reqwidth .frame1.b]
set medium [winfo reqwidth .frame2.c]
set tiny [winfo reqwidth .frame2.d]
set pady [expr [winfo reqheight .frame2.c]-[winfo reqheight .frame2.d]]
pack append .frame1 .frame1.a "filly pady $pady"
pack append .frame1 .frame1.b "fillx padx [expr $long-$short] filly pady $pady"pack append .frame2 .frame2.c "fillx padx [expr $long-$medium] filly"
pack append .frame2 .frame2.d "fillx padx [expr $long-$tiny] filly pady $pady"
pack append . .frame1 {left} .frame2 {left}
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.F.7. Till Brychcy が,以下の
ような例題を示してくれてます.
radiobutton .times -text Times -anchor w
radiobutton .helvetica -text Helvetica -anchor w
radiobutton .courier -text Courier -anchor w
pack .times .helvetica .courier -side top -fill x
pack コマンドにではなく,ウィジェットそれ自信のオプションで,anchor を
west に指定する点に注意して下さい.こうすると,packer は幅一杯のボタン
にしてくれます.
------------------------------
-X- Tk で XXX するには,どうしたらいいの?
A10.F.8. [email protected] (Peter Kesch) が,1 つの例題を提
示してくれました.
set default "foobar"
entry .foo -width 25 -state disabled -textvariable default
------------------------------
comp.lang.tcl の よくある質問と回答集 (2/5) の終り
Retrun faq-menu