J3W v.6の解説 HOME

Tcl/TkによるJ3W v.6 の GUI化


Copyright (c) Jun Mizutani 1998


はじめに

Tcl/Tkは簡単にグラフィカルなユーザーインターフェースを構築することが できるスクリプト言語ということなので,実際にどの程度のことが簡単に実現 できるのかテストしてみました.

結果は「Tcl/Tk使い」の人にとっては当然の事 かも知れませんが,プログラム 本体(ここではj3wとj3dasm)にはまったく手を加えることなしでGUI化する 事が可能でした.Tcl/Tkの学習を含めて実質1週間ほどで十分実用的なアプリ ケーションとすることができました.画面の例

Linux版のj3wでは,実行するファイル名を引数として与えて実行する必要が あります.bash, tcshでファイル名補完を使用すれば特に不便を感じることは ありませんが,Windows95版ではファイルオープンダイアログやスクロール可能 な独立したテキストウィンドウを持っているなど「見かけの完成度」は高く感 じられます.

必要な機能

j3w と j3dasmは標準出力への出力があります.テキストウインドウに表示す るために, 標準出力を取得して Tcl/Tk の上でテキストウィジェットする必要 があります.

  1. j3dasm
    通常のコマンド(例えば ls)と同様に起動した後は,標準出力に結果を書き 出して終了するため,パイプから read した内容をテキストウィジェットに 追加すれば良い.

  2. j3w
    実行はすぐに終了するとは限らず,時間の経過とともに標準出力に少しづつ 書き出される場合(例えばmultiprc.j3s)がある.またj3wの実行中にテキスト ウィンドウのサイズ変更などグラフィックウィンドウの表示中にもテキスト ウインドウを更新する必要がある. つまりコマンドの終了を待ってからテキストウィジェットに結果を書き出す方法 は使用できない.
j3wを実行させる場合は,バックグラウンドで起動したj3wの標準出力を監視してテキスト ウィジェットに常に書き出す必要があります.

スクリプト

#!/usr/bin/wish 

# GUI Frontend for j3w and j3dasm
#   Jun Mizutani  12/23/97 - 1/4/98

. configure -width 400 -height 400

frame .f0
frame .f1
text .f1.t0 -wrap none \
            -xscrollcommand ".f1.sx set" \
            -yscrollcommand ".f1.sy set"
scrollbar .f1.sx -orient horizontal -command ".f1.t0 xview"
scrollbar .f1.sy -orient vertical   -command ".f1.t0 yview"

set pipe 0

button .b0 -text "Execute j3w" -command {
    global pipe
    set types {
        {{j3w object files} {.j3d}}
        {{All files}        *     }
    }
    set filename [tk_getOpenFile -filetypes $types]
    if {$filename != ""} {
         set pipe [open "|j3w $filename"]
         fconfigure $pipe -buffering none
         fileevent $pipe readable showtext
    }
}

button .b1 -text "Assemble Source" -command {
    set types {
        {{j3w source files} {.j3s}}
        {{All files}        *     }
    }
    set filename [tk_getOpenFile -filetypes $types]
    if {$filename != ""} {
         set pipe2 [open "|j3dasm $filename"]
         set t [read $pipe2]
         .f1.t0 insert end $t
    }
}

button .b2 -text "Quit" -command "exit"

proc showtext { } {
    global pipe
    if [eof $pipe] { 
        catch {close $pipe}
        return
    }
        set t [read $pipe 1]
        set s $t
        while { $s > 127 } { 
            set s [read $pipe 1]
            append t $s
        }
        .f1.t0 insert end $t
        update idletasks
}

place .f0 -relx 0.0 -rely 0.0  -relwidth 1.0 -relheight 0.08
place .f1 -relx 0.0 -rely 0.08 -relwidth 1.0 -relheight 0.92
place .b0 -in .f0 -relx 0.0   -rely 0.0 -relwidth 0.333 -relheight 1.0
place .b1 -in .f0 -relx 0.333 -rely 0.0 -relwidth 0.333 -relheight 1.0 
place .b2 -in .f0 -relx 0.667 -rely 0.0 -relwidth 0.333 -relheight 1.0 
pack .f1.sx -side bottom -fill x
pack .f1.sy -side right  -fill y
pack .f1.t0 -side left -fill both -expand true

while {1} {
    update
    after 100
}
以上のスクリプトを j3 というファイル名で保存して,
bash$ wish j3
として実際に起動してみてください.wishが /usr/bin にあれば(which wish で確認)
bash$ chmod a+x j3
とすれば,
bash$ j3
で実行できます.

上部に3つのボタンを持つウィンドウが表示されます. (画面の例) このウィンドウは2つのフレームを持ち,上のフレーム(.f0)は3つのボタン, 下のフレーム(.f1)はテキストウィジェットと垂直(sy)と水平(sx)のスクロールバーを 持っています.

各ボタンの動作

[Execute j3w]
j3dファイルを選択するファイルオープンダイアログを開きます. 選択されたj3dファイルを引数としてj3wをバックグラウンドで起動します. 標準出力はパイプに送られます.パイプに読み出し可能なデータがあると showtext手続きが呼ばれ,テキストウィジェットに表示します.
[Assemble Source]
j3sファイルを選択するファイルオープンダイアログを開きます. 選択されたj3dファイルを引数としてj3dasmをバックグラウンドで起動します. 標準出力はパイプに送られます.パイプからすべて読み出した後,テキスト ウィジェットに表示します.
[Quit]
スクリプトを終了します.


TODO

例えば サンプルのlist4.j3d等のようにグラフィック画面を開かないでキー入力 を必要とする場合,キー入力の取得ができません.
今回の例はTcl/Tkで作成した最初のスクリプトです.完成版ではありませんが,色々改造 して試してみてください.そこがスクリプト言語のいい所です.
もっと良い書き方があると思います.特にwhileの無限ループ部分は美しくないと思います. 良い方法があれば,お知らせください.


HOME
ご意見・ご感想は,mizutani.jun@nifty.ne.jp まで.

水谷 純(mizutani.jun@nifty.ne.jp)