Wish Tcl/Tk 入門

Wish Tcl/Tk 入門

6. メニューバーの設定

menu, menubutton, tk_messageBox, switch, configure

Window のソフトには大体あるのが、メニューバーです。これも tk で簡単に作成することができます。menu と menubutton の 2 つの 方法があります。

6.1 menu による メニューバーの作成

(実行例 6.1) メニューバーを作って、file の中に終了メニューを 作ります。
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" "$@"
# menu1.tcl
# 簡単な メニュー を作ります。
#
wm title . menu1-tcl
#
# configure command で . に メニューバー .m1 を作ります。
#
. configure -menu .m1
menu .m1
#
# .m1 の下に file color という メニューを作ります。
#     -tearoff no 切り離しはしない。
#   add cascade です。
.m1 add cascade -label ファイル -menu .m1.file
.m1 add cascade -label 色       -menu .m1.color
menu .m1.file -tearoff no
menu .m1.color -tearoff no
#
# .m1.file .m1.color の下に コマンドを作ります。
#
.m1.file  add command -label ベル -command bell
.m1.file  add command -label 終了 -command exit
.m1.color add command -label red  -command { setcolor red }
.m1.color add command -label blue -command { setcolor blue }
#
# label を作ります。pack で表示します。
#
global iro
set iro "色は無選択です。"
label .lb1 -textvariable iro 
pack .lb1 -ipady 30 -fill both -expand yes
#
# setcolor は proc で定義します。
# iro が global 変数でつながっています。
#
proc setcolor { color } {
#
# configure command で .lb1 の foreground の 色を再指定
#
global iro
.lb1 configure -fg $color
set iro "$color の色が選択されました。"
}

実行すると、ファイルと色というメニューができます。

ファイルのボタンを押すと、pop up で ベル と 終了がでてき ます。ベルを押すと ベルがなります。終了を押すと終了します。

色のボタンを押すと、赤と青の選択があり、label の 色を変 更する proc の setcolor が呼び出されます。

menu command で メニューを作って、.menu add command で command を作ります。add は このほかに、checkbutton (チェック ボタン)、radiobutton (ラジオボタン)、separator (仕切り線) な どを add することが出来ます。

メニューは、階層構造で深く作ることができます。その場合に は横にメニューが現れます。menu command で . で lebel を深く して行けば良いのです。

6.2 アクセラレーター と ショートカット

(実行例 6.2) Window の menu が通常は見えないのは、 なれて来たら、このメニューを開かないでも処理ができるように キー操作で 処理することをつなげるの世の習いです。その 方法に は、アクセラレーター と ショートカット の 2 つの 方法があり ます。アクセラレーター は cntl キーを 押しながら 別の key を 押すものです。また ショートカットは alt key を 押しながら 別 の key で実現します。後者は menu の 中で -underline command で 実現できます。アクセラレータは bind で key 操作と繋げるこ とをします。-underline は alphabet の key のみ有効です。
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" "$@"
# menu2.tcl
# メニュー にアクセレレータやショートカットをつけます。
#
wm title . menu2-tcl
#
# configure command で . に メニューバー .m1 を作ります。
#
. configure -menu .m1 
menu .m1
#
# .m1 の下に file color という メニューを作ります。
#     -tearoff no 切り離しはしない。
#   add cascade です。
#
# 先頭文字(英語) -underline 0 でメニューの選択が可能です。
# 例えば Alt + C で 色選択 その後 Alt + r で色の赤選択です。
#
.m1 add cascade -label F:ファイル -underline 0 -menu .m1.file
.m1 add cascade -label C:色 -underline 0 -menu .m1.color 
menu .m1.file -tearoff no
menu .m1.color -tearoff no
#
# .m1.file の下にアクセレレータを付けます。
# bind で アクセレレータ と command の関係を作る必要があります。
# これだと menu を 選択しないでも Cntl-b で ベルの選択になります。
#
.m1.file  add command -label ベル -command bell \
	-accelerator "Cntl+B"
bind all  { bell }
#
.m1.file  add command -label 終了 -command exit \
	-accelerator "Cntl+C"
bind all  { exit }
#
# .m1.color の下にはショートカットを付けます。
# -underline 0 は 先頭文字(英語に限る) を key にします。
# メニューを選択して、先頭文字をいれると 動作します。
.m1.color add command -label red  -command { setcolor red } \
  -underline 0
.m1.color add command -label blue -command { setcolor blue } \
  -underline 0
#
# label を作ります。pack で表示します。
#
global iro
set iro "色は無選択です。"
label .lb1 -textvariable iro 
pack .lb1 -ipady 30 -fill both -expand yes
# 大きさを整えるために .dum を 作ります。
frame .dum -width 200 -height 10
pack .dum -side top -fill both -expand yes
#
# setcolor は proc で定義します。
# iro が global 変数でつながっています。
#
proc setcolor { color } {
#
# configure command で .lb1 の foreground の 色を再指定
#
global iro
.lb1 configure -fg $color
set iro "$color の色が選択されました。"
}

基本的には、同じですがメニュー操作がマウスを必要としませ ん。キーボードになれている人はマウスは触りたくないでしょう。 Cntl-B (以下 C-b と 略す。) で ベルが選択できます。ファイル のメニューを開くには、Alt+F (以下 M-F と略す) で 可能です。

ショートカットの場合には、色の選択の メニュー M-c をして 開いてから、M-r (赤) をしないと動作しません。つまり 単に M-r では動作しません。M-c M-r が必要です。

アクセラレーターの場合には、bind で 関係付けていますので、 そちらでも動作します。もちろんマウスで メニューをopen しても 動作します。

ショートカットやアクセラレーターをたくさん作りますと、動 作は素早くできますが、逆に誤った動作も考えられます。とくにこ の例では、M-c と C-c は 同じ c を使っていますので、誤る可能 性があります。こういう設定は実際には避けましょう。またプログ ラムを終了や消去するときには、確認をとるようにすると良いと思 います。

6.3 メニューボタンを使う例。確認をとる例

menu command の他に、menubutton (メニューボタン) を button のような 部品(widget) の一つとして使うことができます。この場 合メニューバーは frame で作ります。とくに、メニューのバーの 部分に menu 以外の部品 (label) 等を同時に出したいときには、 menu ではうまくできません。menubutton ならできます。また終了 のときに 確認の window を作る例(tk_messageBox)を併せてしめし ます。switch での 分岐も説明します。
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" "$@"
# menu3.tcl
# メニュー にアクセレレータやショートカットをつけます。
#
wm title . menu3-tcl
#
# frame command で . に メニューバー .m1 を作ります。
# frame を宣言したら、frame をどこに置くか pack で宣言します。
#
frame .m1 -relief raised -borderwidth 2
pack .m1 -side top -fill x
#
# .m1 の下に file color という メニューを作ります。
#     -tearoff no 切り離しはしない。
#   add cascade です。
#
# menubutton は -label でなく -text です。
# menubutton にも 新たに名前が必要です。
#
# 先頭文字(英語) -underline 0 でメニューの選択が可能です。
# 例えば Alt + C で 色選択 その後 Alt + r で色の赤選択です。
#
menubutton .m1.mb1 -text F:ファイル -underline 0 -menu .m1.mb1.file
menubutton .m1.mb2 -text C:色 -underline 0 -menu .m1.mb2.color 
#
set color none
set iro $color
label .m1.lb1 -text "現在の色="
label .m1.lb2 -textvariable iro
pack  .m1.mb1 .m1.mb2 .m1.lb1 .m1.lb2 -side left -expand yes -fill x
#
# 後の記述は menu2.tcl と同じです。ただし、.m1.mb1 または 
# .m1.mb2 の下に全てなります。
#
# .m11.mb1.file の下にアクセレレータを付けます。
# bind で アクセレレータ と command の関係を作る必要があります。
# これだと menu を 選択しないでも Cntl-b で ベルの選択になります。
#
menu .m1.mb1.file -tearoff no
menu .m1.mb2.color -tearoff no
#
.m1.mb1.file  add command -label ベル -command bell \
	-accelerator "Cntl+B"
bind all  { bell }
#
# shuuryou は 下で proc で 定義します。
#
.m1.mb1.file  add command -label 終了 -command shuuryou \
	-accelerator "Cntl+C"
bind all  { shuuryou }
#
# .m1.mb2.color の下にはショートカットを付けます。
# -underline 0 は 先頭文字(英語に限る) を key にします。
# メニューを選択して、先頭文字をいれると 動作します。
.m1.mb2.color add command -label red  -command { setcolor red } \
  -underline 0
.m1.mb2.color add command -label blue -command { setcolor blue } \
  -underline 0
#
# label を作ります。pack で表示します。
#
global iro
# 大きさを整えるために .dum を 作ります。
frame .dum -width 200 -height 50
pack .dum -side top -fill both -expand yes
#
# setcolor は proc で定義します。
# iro が global 変数でつながっています。
#
proc setcolor { color } {
#
# configure command で .lb1 の foreground の 色を再指定
#
global iro
.dum configure -bg $color
.m1.lb2 configure -fg $color
set iro $color
}
#
# shuuryou は proc で 定義します。
#
proc shuuryou {} {
#
# 本当に終了するか聞きます。
# tk_messageBox の結果 [ ... ] を answer にいれます。
#           @ 大文字です。注意
set answer [ tk_messageBox -parent . \
      -title "kakunin" -icon warning \
      -type okcancel -message "終了しますか?" ]
# -icon には error, info, question, warning があります。
# -type には abortretryignore, ok, okcancel, 
#            retrycancel, yesnocancel があります。
#
# switch $answer の 内容で判断します。この場合には default に
# なる場合はありませんが、一応念のためいれておきました。
#
switch $answer {
ok exit
cancel return
default return
}
}

実行しますと、現在の色の表示が frame で 作った menu の上 にできます。

終了しようと思うと、確認のボタンがでます。面倒でもこうい う安全装置はプログラムの信頼性を高めます。


rsaito@ee.uec.ac.jp