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クラスは,メニューを出現させるボタンを定義しています.インスタンス変数を以下に示します.
| インスタンス変数名 | 役割 |
|---|---|
| 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の実体をインスタンスとするクラスです.インスタンス変数とメソッドの例を以下に示します.
| インスタンス変数名 | 役割 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 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のリファレンスを参照して下さい.
|
メニューボタンやラジオボタン,カスケードもできます.ちょっと見苦しいプログラムですが,サンプルを記述しました.
#!/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
上記のプログラムを走らせると,下のようなメニューができます.(画像は合成しています.)