メニュー(Menu)

メニューとは一般的なアプリケーションで見られる,ウィンドウの左肩にあるボタンとその実体のことです.メニューウィジェットはボタンを押しっぱなしにすると,内容が出現し,選択したいところまでドラッグしてリリースすると,何らかの働きをするウィジェットです.

Ruby/Tkではいくつか方法がありますが,ここではTkMenubuttonクラスとTkMenuクラスを併用することで実現することにします.ほかにもTkMenubarクラスがありますが,筆者はTkMenubarクラスでのカスケードの使用方法がまだ分からないので前者の方法だけ紹介します.

使用例を示します.

#!/usr/local/bin/ruby

require 'tk'

var = TkVariable.new('')

frame = TkFrame.new(nil)
frame.pack('side' => 'top', 'fill' => 'x')

menubutton = TkMenubutton.new(frame,
			  'text' => 'menu')
menu = TkMenu.new(menubutton,
		   'tearoff' => 'off')
menu.add('command',
	 'label' => '春',
	 'command' => proc{var.value = 'あけぼの'})
menu.add('command',
	 'label' => '夏',
	 'command' => proc{var.value = 'よる'})
menu.add('command',
	 'label' => '秋',
	 'command' => proc{var.value = 'ゆふぐれ'})
menu.add('command',
	 'label' => '冬',
	 'command' => proc{var.value = 'つとめて'})
menu.add('separator')
menu.add('command',
	 'label' => 'Quit',
	 'command' => proc{exit})
menubutton.menu(menu)
menubutton.pack('side' => 'left')

label = TkLabel.new(nil,
		    'width' => 15,
                    'height' => 10,
		    'background' => 'darkgreen',
		    'foreground' => 'white',
		    'textvariable' => var)
label.pack('side' => 'top', 'fill' => 'both')

Tk.mainloop
上記のプログラムを走らせると,最初下のようになります.

menuボタン上で押したままドラッグすると,以下の様になります.(画像はメニューの特性上合成してあります.)

さらに'春'に合わせてリリースすると,以下の様になります.

TkMenubuttonクラスは,メニューを出現させるボタンを定義しています.インスタンス変数を以下に示します.

TkMenubuttonクラスのインスタンス変数(抄)
インスタンス変数名 役割
activebackground マウスが乗っているときの背景色.
activeforeground マウスが乗っているときの前景色.
background 背景色.
foreground 前景色.
disabledforeground disabled状態のときの前景色.
anchor 配置場所.'n','e','s','w','center'等で指定.
bitmap 表示するbitmap.TkBitmapImageオブジェクトで指定.
image 表示するimage.TkPhotoImageオブジェクトで指定.
text 表示する文字列.
textvariable 表示する文字列変数.TkVariableオブジェクトで指定.
justify 文字列をよせる側."left","center","right"で指定.
borderwidth 枠の幅.整数値で指定.
cursor マウスカーソルの形.
highlightcolor ウィジェットにフォーカスがある時の枠の色.
highlightthickness ウィジェットにフォーカスがある時の枠の幅.
relief ウィジェットの凹凸.'raised'または'sunken'で指定.
wraplength 折り畳むときの1行の文字数.
height ウィジェットの高さ.
width ウィジェットの幅.
indication メニューボタンの右側に小さな四角が表示されます.0(非表示)または1(表示)を指定します.
state ボタンの状態です.'normal','active'または'disabled'で指定します.'disabled'にすると,ボタンが反応しません.
menu メニューの内容.TkMenuクラスのオブジェクトで指定します.

TkMenuクラスはMenuの実体をインスタンスとするクラスです.インスタンス変数とメソッドの例を以下に示します.

TkMenuクラスのインスタンス変数とメソッド(抄)
インスタンス変数名 役割
activebackground マウスが乗っているときの背景色.
activeforeground マウスが乗っているときの前景色.
background 背景色.
foreground 背景色.
borderwidth 枠の幅.整数値で指定.
cursor マウスカーソルの形.
relief ウィジェットの凹凸.'raised'または'sunken'で指定.
tearoff 選択したとき,メニューを別ウィンドウで表示させることができる破線を生成するかどうかを指定します.'on','off'で指定します.
メソッド名 機能
add(str[,hash_args..]) strには'command','separator','checkbutton','radiobutton',または'cascade'が入ります.'hash_args..'は,strが選択されたときのそれぞれのインスタンス変数をハッシュ形式で設定します.説明は割愛しますが,下のサンプルおよびTcl/Tkのリファレンスを参照して下さい.
'command': 選択した場合,コマンドを実行します.
'separator': 横線を入れます.
'checkbutton': チェックボタンです.TkCheckButtonとほぼ同様のインスタンスを持ちます.
'radiobutton': ラジオボタンです.TkRadioButtonとほぼ同様のインスタンスを持ちます.
'cascade': 選択した場合,サブメニューを開きます.サブメニューはTkMenuクラスで指定します.

メニューボタンやラジオボタン,カスケードもできます.ちょっと見苦しいプログラムですが,サンプルを記述しました.

#!/usr/local/bin/ruby

require 'tk'

var = TkVariable.new('')
bgcolor = TkVariable.new('darkgreen')
fgcolor = TkVariable.new('white')

frame = TkFrame.new(nil)
frame.pack('side' => 'top', 'fill' => 'x')

menubutton = TkMenubutton.new(frame,
			  'text' => 'menu')

label = TkLabel.new(nil,
		    'width' => 15,
		    'height' => 10,
		    'background' => 'darkgreen',
		    'foreground' => 'white',
		    'textvariable' => var)

menu = TkMenu.new(menubutton,
		   'tearoff' => 'off')
menu.add('command',
	 'label' => '春',
	 'command' => proc{var.value = 'あけぼの'})
menu.add('command',
	 'label' => '夏',
	 'command' => proc{var.value = 'よる'})
menu.add('command',
	 'label' => '秋',
	 'command' => proc{var.value = 'ゆふぐれ'})
menu.add('command',
	 'label' => '冬',
	 'command' => proc{var.value = 'つとめて'})
menu.add('separator')
submenu = TkMenu.new(menubutton,
		     'tearoff' => 'off')
submenu.add('checkbutton',
	    'label' => '背景色を青にする',
	    'onvalue' => 'blue',
	    'offvalue' => 'darkgreen',
	    'variable' => bgcolor,
	    'command' => proc{label.background(bgcolor.value)})
submenu.add('separator')
submenu.add('radiobutton',
	    'label' => '前景色を黄色にする',
	    'value' => 'yellow',
	    'variable' => fgcolor,
	    'command' => proc{label.foreground(fgcolor.value)})
submenu.add('radiobutton',
	    'label' => '前景色を白色にする',
	    'value' => 'white',
	    'variable' => fgcolor,
	    'command' => proc{label.foreground(fgcolor.value)})
menu.add('cascade',
	 'label' => 'サブメニュー',
	 'menu' => submenu)
menu.add('separator')
menu.add('command',
	 'label' => 'Quit',
	 'command' => proc{exit})
menubutton.menu(menu)

menubutton.pack('side' => 'left')
label.pack('side' => 'top', 'fill' => 'both')

Tk.mainloop
上記のプログラムを走らせると,下のようなメニューができます.(画像は合成しています.)


戻る