1#!/usr/bin/env ruby 2# This script is a re-implementation of tktimer.rb with TkTimer(TkAfter) class. 3 4require "tk" 5 6root = TkRoot.new(:title=>'realtime timer sample') 7 8f1 = TkFrame.new(:borderwidth=>2, :relief=>:ridge) 9f1.pack(:side=>:bottom, :fill=>:both) 10TkLabel.new(f1, :text=>'use TkTimer (TkAfter) class').pack(:anchor=>:center) 11label1 = TkLabel.new(:parent=>f1, :relief=>:raised, 12 :width=>10).pack(:fill=>:both) 13 14f2 = TkFrame.new(:borderwidth=>2, :relief=>:ridge) 15f2.pack(:side=>:bottom, :fill=>:both) 16TkLabel.new(f2, :text=>'use TkRTTimer class').pack 17label2 = TkLabel.new(:parent=>f2, :relief=>:raised, 18 :width=>10).pack(:fill=>:both) 19 20TkLabel.new(:padx=>10, :pady=>5, :justify=>'left', :text=><<EOT).pack 21Interval setting of each timer object is 10 ms. 22Each timer object counts up the value on each callback 23(the value is not the clock data). 24The count of the TkTimer object is delayed by execution 25time of callbacks and inaccuracy of interval. 26On the other hand, the count of the TkRTTimer object is 27not delayed. Its callback interval is not accurate too. 28But it can compute error correction about the time when 29a callback should start. 30EOT 31 32# define the procedure repeated by the TkTimer object 33tick = proc{|aobj| #<== TkTimer object 34 cnt = aobj.return_value + 1 # return_value keeps a result of the last proc 35 label = aobj.current_args[0] 36 label.text format("%d.%02d", *(cnt.divmod(100))) 37 cnt #==> return value is kept by TkTimer object 38 # (so, can be send to the next repeat-proc) 39} 40 41timer1 = TkTimer.new(10, -1, [tick, label1]) # 10 ms interval 42timer2 = TkRTTimer.new(10, -1, [tick, label2]) # 10 ms interval 43 44timer1.start(0, proc{ label1.text('0.00'); 0 }) 45timer2.start(0, proc{ label2.text('0.00'); 0 }) 46 47b_start = TkButton.new(:text=>'Start', :state=>:disabled) { 48 pack(:side=>:left, :fill=>:both, :expand=>true) 49} 50 51b_stop = TkButton.new(:text=>'Stop', :state=>:normal) { 52 pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes') 53} 54 55b_start.command { 56 timer1.continue 57 timer2.continue 58 b_stop.state(:normal) 59 b_start.state(:disabled) 60} 61 62b_stop.command { 63 timer1.stop 64 timer2.stop 65 b_start.state(:normal) 66 b_stop.state(:disabled) 67} 68 69TkButton.new(:text=>'Reset', :state=>:normal) { 70 command { timer1.reset; timer2.reset } 71 pack(:side=>:right, :fill=>:both, :expand=>:yes) 72} 73 74ev_quit = TkVirtualEvent.new('Control-c', 'Control-q') 75Tk.root.bind(ev_quit, proc{Tk.exit}).focus 76 77Tk.mainloop 78