Node.jsからTcl/Tkを制御する。
JavaScript初心者の高木です。おはようございます。
バカバカしいことでも大真面目に取り組めば面白い結果を導けるものです。
今回もそうした考えから挑戦してみました。
JavaScript初心者の私にはちょうどよいテーマだったと思います。
今回のお題は「Node.jsからTcl/Tkを制御する」です。
まずはやりたいことから説明します。
上記のような簡単なウィンドウを作ります。
このウィンドウには、ちょっとわかりにくいかもしれませんが、ラベルとボタンを貼っています。
ラベルには空の文字列を設定しているので、ボタンの上にスペースだけ取っています。
Tcl/Tkのスクリプトは次のようになります。
1 2 3 4 5 6 | # test.tcl label .l -text " " button .b -text test -command { puts pushed } pack .l .b |
これをJavaScriptから呼び出したいと思います。
JavaScriptのスクリプトは次のようにしました。
1 2 3 4 | // test.js var child_process = require('child_process'); let child = child_process.spawn('wish'); child.stdin.write("source test.tcl\n"); |
ざっと解説すると、Tcl/Tkのコマンドであるwishをchild_processを使って実行しています。
子プロセスの標準入出力を使ってプロセス間通信を行うことができます。
ここでは、child.stdin.writeで子プロセス(すなわちwish)の標準入力にTclのコマンドを書き込んでいます。
sourceコマンドを使って、先ほどのtest.tclを実行させているのです。
これだけではウィンドウは表示できますが、ボタンを押したときの処理を行うことができません。
Tcl側では、ボタンを押すとpushedという文字列を標準出力に書き込んでいます。
この文字列をそのままラベルに表示したいと思います。
JavaScript側を次のように追記することで、実現することができました。
1 2 3 4 5 6 7 8 | // test.js var child_process = require('child_process'); let child = child_process.spawn('wish'); child.stdin.write("source test.tcl\n"); child.stdout.on('data', (data) => { child.stdin.write(`.l configure -text ${data}\n`); }); |
child.stdout.onで、子プロセスが標準出力に書き込んだときのイベント処理を記述しています。
今回はwishを引数無しで呼び出していますので、対話的にコマンドを発行することができます。
子プロセスの標準入力に.l configure -text ${data}というTclコマンドを直接書き込んでいます。
これでボタンを押せば、ラベルにpushedが表示されるようになりました。
今回の例は非常に単純なものですが、これを応用すればJavaScriptから自在にTcl/Tkを制御できることがわかりました。