MSP:Mine Sweeper Project

2004-12-11

Ruby/Tk編(3) タイマーを仕込む

なんとなく見た目ができたところで機能の作りこみ、まずはタイマーである。
単純にボタンを押したら数字をカウントアップ、もう一度押したら停止、としてみる。

こ こでふと考える。周期的にイベントを発生するのは、制御側(Ruby)か、UI(Tk)側のどっちがいいのだろう。タイマー機能というものは見た目には 関係ないものだからUI側から分離したほうが自然なような気もするが、そうするとRuby側でThreadを使ってイベント生成、という面倒なことにな る。Windows版RubyはThreadで制約があるので安直にTkのTkAfter(またはTkTimer)を使うことにする。

タ イマーをUI・ツールキット側に含めたほうが簡単というは、Ruby+Tkという組み合わせに限ったことでない。ツールキットは外部からのイベント(主に ユーザー入力)を処理するインタフェースであり、イベント駆動型の構成となる。だからツールキットはループで処理されることになる。するとループの外には イベントが発生しない限りとばなくなるので、制御側にタイマーをおくためには、制御側とは独立にイベントを発生させる機構が必要になる。
というわけで、タイマーはツールキットに頼っとけば吉としておこう。

さて、実装である。
TkのタイマーといえばTkAfter(またはTkTimer)。メソッドはここを参照。色々あるが、startとstopでいいだろ。

# カウンター用のフレームを作成
TkFrame.new($puzzle_demo) {|lblframe|
borderwidth 2
relief 'sunken'
remain = TkLabel.new(lblframe) {
font $font
justify 'left'
text "labeltest"
}
remain.pack('side'=>'left','expand'=>'true' )

TkButton.new(lblframe) {
text '(^_^)'
command proc{
text '(*_*)'
$timecnt.start

}
}.pack('side'=>'left','expand'=>'true')

$counterlbl = TkLabel.new(lblframe) {
font $font
justify 'left'
text "0"
}
$counterlbl.pack('side'=>'left','expand'=>'true')

}.pack('side'=>'top', 'fill'=>'x', 'pady'=>'2m')

#タイマー生成
$timecnt = TkAfter.new( 1000, -1, proc {
$counterlbl.text = $counterlbl.text.to_i+1
} )