From: Yuji Shigehiro Date: 1997-10-30T21:38:07+09:00 Subject: [ruby-list:5186] Re: ruby & tk(wish) しげひろです. 複数の thread から一つの ウィジェットを叩けるかテストしようと思い, ス クリプトを書いてみました. 実行すると, ウインドウが開きます. create ボタンを押すと, 別 thread を 起こし, canvas 内で○を動かします. stop ボタンを押すと thread を殺しま す. ---- ここから ---- #! /usr/local/bin/ruby require "tcltk" # 別 thread で canvas に ○ を作って動かすオブジェクト class Circle # 引数は, tcl/tk インタプリタ, 親ウィジェット, canvas ウィジェット def initialize(ip, parent, c) # おまじない button, destroy, pack = ip.commands().indexes("button", "destroy", "pack") # ○の位置, 速度 @x = 10; @y = 10; @dx = rand(2) + 1; @dy = rand(2) + 1 # ○を生成する @id = c.e("create oval #{@x - 5} #{@y - 5} #{@x + 5} #{@y + 5}") # 自 thread を止めるコールバックとボタン th = Thread.current # 自 thread b1 = nil # コールバック c1 = TclTkCallback.new(ip, proc{ c.e("delete", @id) # ○を消す destroy.e(b1) # 自分自身のためのボタンを消す Thread.kill th # thread を止める # コールバックはメインの thread から呼ばれるので # Thread.exit してはいけない }) # ボタン生成 b1 = TclTkWidget.new(ip, parent, button, "-text stop -command", c1) pack.e(b1) # 生成したボタンを表示 # ○を移動し続ける while TRUE c.e("coords", @id, @x - 5, @y - 5, @x + 5, @y + 5) if @x < 0 || @x > 200 @dx = -@dx end if @y < 0 || @y > 200 @dy = -@dy end @x += @dx; @y += @dy Thread.pass end end end # おまじない ip = TclTkInterpreter.new() root = ip.rootwidget() button, canvas, pack, update = ip.commands().indexes("button", "canvas", "pack", "update") # canvas ウィジェット c = TclTkWidget.new(ip, root, canvas) # thread を生成するコールバックとボタン c1 = TclTkCallback.new(ip, proc{Thread.new{c = Circle.new(ip, root, c)}}) b1 = TclTkWidget.new(ip, root, button, "-text create -command", c1) # 終了ボタン c2 = TclTkCallback.new(ip, proc{ exit }) b2 = TclTkWidget.new(ip, root, button, "-text exit -command", c2) pack.e(b1, b2, c) # ボタンを表示 # メインループ while TRUE update.e() Thread.pass end ---- ここまで ---- ---- 重弘裕二 阪大情報処理教育センター (sigehiro@rd.ecip.osaka-u.ac.jp) 阪大工情報システム白川研 (sigehiro@ise.eng.osaka-u.ac.jp)