例題(Button)


この例は、klitcl を用いた非常に簡単なプログラムとなっています。
KLIC 側から、Tcl/Tk にアクセスし、ボタンを作成します。
このボタンをユーザが押すことにより、プログラムが終了します。

プログラム

プログラムを以下に示します。
 1: % button.kl1
 2:
 3: :- module main.
 4:
 5: main :- klitcl:klitcl_init(S),
 6:         klitcl:tcltk_init-S,
 7:         klitcl:tcl_eval("button .b -text Quit \
 8:                          -command {klic main quit}",_)-S,
 9:         klitcl:tcl_eval("pack .b",_)-S,
10:         klitcl:tk_mainloop-S,
11:         S = [].
12:
13: quit(_,I,O) :- Mes = "Button Pushed.",
14:         io:outstream([print(Mes),nl]),
15:         klitcl:tcl_quit(I,O1),
16:         klitcl:klitcl_quit(O1,O).

コンパイル

このプログラムは、sample/button のディレクトリにあります。
このプログラムを利用する前に、トップディレクトリで make を行い、 klitcld をコンパイルしておいてください。
このプログラムをコンパイルするには、このディレクトリで make すればOKです。
コンパイルが終了すると、button という名前の実行ファイルが出来ていると思います。

実行

まず、klitcld を実行します。これは、Tcl/Tk を実行するためのプログラムです。
% ./kltcld &
のようにして、バッググラウンドで実行させるとよいでしょう。
このあと、
% ./button
とすると、プログラムが動作し、Tk のボタンウィジェットにより作られたボタンが表示されます。これは、「Quit」と書かれたボタンで、

Quit

のようになります。
ここで、このボタンを押すと、実際にプログラムが終了してボタンが消え、また、先に実行していた klitcld も終了します。
このとき、button を実行した方の標準出力には「"Button Pushed."」というメッセージが表示されます。

プログラムの説明

最初に呼ばれている述語 klitcl_init は、klitcl の初期化を行なっています。
引数は、ユーザプログラムが klitcl に命令等を発行するためのストリームです。

次に、tcltk_init が呼ばれます。
この述語が呼ばれることにより、klitcld 内部に Tcl インタープリタが生成され、Tk のメインウィンドゥが作られます。
本来、tcltk_init は引数を 2 つとる述語ですが、KLIC の引数対の展開機能を用いることにより、簡単な表記で述語を呼ぶことができます。

main の3,4,5行目の tcl_eval により、実際に Tcl に処理をさせます。
tcl_eval の最初の引数は Tcl のコマンド文字列です。
ここでは、

の2つのコマンドを実行しています。
tcl_evalの2つ目の引数は、結果を表わす文字列ですが、ここでは使わないので、無名変数(_)にしています。
3つ目および4 つ目の引数にはストリームが来ますが、ここでも引数対により表記を省略しています。

main の5行目の tcl_eval により実行されているのは、「pack」ですので、ここで、作成されたボタンが画面に表示されることになります。
そして、次の行の「tk_mainloop」により、Tk のイベント待ちループを起動します。

ここで main の 3 行目の、ボタンを生成している行に注目すると、「klic」というコマンドがボタンにバインドされています。
これは、Tcl 側から KLIC の述語を呼ぶために拡張された命令であり、少なくとも 2 つの引数を取ります。
最初の引数は、呼ばれる述語が存在するモジュール名で、次に来る引数は、呼ばれる述語名です。
それ以降に引数があった場合は、その全てが述語に渡されるべき引数としてKLIC 側に渡されます。
この引数は、KLIC側に、文字列のリストとして渡されます。 このサンプルプログラムでは、ボタンを押すことにより呼ばれる述語に引数は必要ないので、KLIC コマンドの引数は2つだけになっています。

述語 main:quit/3 の定義が、呼ばれる方の述語の書きかたのサンプルになっています。 呼ばれる述語は、必ず 3 つの引数をとります。
1つ目の引数は、Tcl 側から与えられた引数のリストです。
たとえば、Tcl 側で「klic main test foo bar」のようにして呼ばれた述語「main:test」の最初の引数は、["foo","bar"]というリストになります。
リストの要素は全て文字列であることに注意して下さい。
2つ目と3つ目の引数は、klitcl のストリームです。

ボタンが押されたときに呼ばれる main:quit/3 は、tcl_quit を呼んで klitcld を終了させ、その後に klitcl_quit を呼ぶことによりプログラムを終了させています(15,16行目)。

なお、このサンプルを見てわかる通り、klitcl の述語はすべて klitcl というモジュール内の述語として定義されているので、呼び出す際には,「klitcl:述語名」 とする必要があります。