Wish Tcl/Tk 入門5. サブルーチン proc |
#!/bin/sh # the next line restarts using wish \ exec wish "$0" "$@" # passwd.tcl 5.1 # # proc でも main でも共通する global 変数 を 宣言 # ok, login, passwd の 3 つの 変数です。 # global ok login passwd # set ok "Tab:入力切替 CR:実行" # # ラベルを 4 つのフレームに分割して所属させ # pack の表示を意図した並び方にします。 # frame .f0 frame .f1 frame .f2 frame .f3 # # いろいろな label を作ります。 # # パスワード の entry は -show * で * で 表示します。 # label .f0.lb0 -text " Welcome to Localhost " -bg white -fg black label .f1.lb1 -text ログイン名 -bg white -fg black entry .f1.en1 -textvariable login -bg white -fg blue label .f2.lb2 -text パスワード -bg white -fg black entry .f2.en2 -textvariable passwd -bg white -fg blue -show * label .f3.lb3 -textvariable ok -bg white # # configure コマンドで .lb3 の -fg の属性を変えます。 # .f3.lb3 configure -fg blue # pack .f0 .f1 .f2 .f3 -fill both -expand yes pack .f0.lb0 -fill both -expand ye pack .f1.lb1 .f1.en1 -side left pack .f2.lb2 .f2.en2 -side left pack .f3.lb3 -side left -fill both -expand yes # # focus で login への入力を促します。 # focus .f1.en1 # 改行で login と passwd の比較がなされます。 # # proc checkPW に 引数 $login と $passwd $ok を引き継ぎます。 # # entry .en1 での 改行はただ passwd field に行かせます。 # entry .en2 の改行と checkPW の呼出を結びます。 # bind .f1.en1{ focus .f2.en2 } bind .f2.en2 { checkPW } # # 手続き checkPW を定義 # proc checkPW { } { # # proc でも global 変数 ok login passwd が有効になるように宣言 # global ok login passwd # if { ( $login == "user" ) && ( $passwd == "pass" ) } { .f3.lb3 configure -fg blue set ok "login は成功" }\ else { .f3.lb3 configure -fg red set ok "login 失敗" } # いずれの場合にも login と passwd の中身を clear します。 # また 入力を login の 位置に持って行きます。 set login "" set passwd "" focus .f1.en1 return }
login 名 user passwd pass で login 成功になります。
login が 失敗したときには、login 失敗は色を configure で 属性を その時点で変更しています。
passwd field で 改行キー login のところで return を押しても普通は何も処理してくれ
ません。ここで bind して passwd の入力窓に移る (focus) する
ようにしました。login が成功しても、失敗しても もとの login
の window に戻るようにしています。
この プログラムは分かりやすいように $passwd の比較は 生
の pass と直接比較しています。この passwd.tcl の ソースが見
える状況ではまったく意味がありません。実際に利用する場合には、
入力した passwd を暗号化し、また pass を 暗号化したものと比
べることが必要です。pass の暗号化したものが ソースで例え見ら
れても、それが何を暗号化したものかを見極めるのは非常に大変で
す。
単位変換は、わかってはいるけどめんどくさいものです。
電卓のように変換できたら便利ですね。それぞれの変換手段を
proc にまとめました。
数値をいれて、変換したい方向のボタンを押します。
ラジオボタンは、押されたボタンの 1つしか on になりません。
3 つ以上ラジオボタンがあっても同じように動作します。
ラジオボタンが押されますと、henkan という 変数にどの proc を
呼ぶか proc 名が入ります。
実行ボタンまたは entry 1 で 改行が押された場合には、
henkan の名前の proc を value の値を引数にして送ります。
そして return で戻されたあたいを再び value の値にいれます。
{ set value [ $henkan $value ] }
の表現は良く使われますので覚えておいてください。
ここで注目したいのは、proc の中で使われている変数は、
メインのプログラムと同じ名前であっても同じ値が入るわけではあ
りません。引数として受け継がれた変数 proc intocm なら 引数で
ある in だけがメインのプログラムの value の値を引き継ぎます。
ですから in と value の名称が異なっても問題ありません。この
方が、この proc を他の目的で他の所に使う場合には大変便利です。
このように proc に 変数値を引き継ぐには global 変数の方
法と、引数として使う場合の 2 つがあります。同じ変数名で両方
同時に指定することはできません。(同時に指定する意味はないは
ずです。) 別の変数なら、2 つの方法を別々に使っても問題があり
ません。関数の値としては引数を、また両方で同じ意味で使う変数
は global 変数と分けて使うのが便利です。
5.2 単位変換電卓
(実行例 5.2) 5.1 の proc は、変数の引渡しは global 変数を用
いていました。ここでは、proc の引数として変数を受渡し、
return と 引数で変数を返します。こうしますと、proc は、独立
した処理として、他のプログラムに拡張しやすくなります。
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" "$@"
# tannihenkan.tcl 5.2
#
# 単位を変換するプログラムです。
#
label .lb1 -text 数値をいれてください。 -bg white
entry .en1 -textvariable value -width 20 -relief ridge -bg yellow
button .bt1 -text 実行 -command { set value [ $henkan $value ] }
#
# 改行でも実行するとします。
#
bind .en1
rsaito@ee.uec.ac.jp