From: Morton Goldberg Date: 2007-08-22T03:45:18+09:00 Subject: Re: TkTimer and calling own methods from handler On Aug 21, 2007, at 8:15 AM, NetManiac wrote: > I'm experimenting with Ruby Tcl/Tk and I've got stuck with timers. I > reduced my problem to following example: > > #!/usr/bin/env ruby > require "tk" > > def advance > button.text = global_var.to_s > global_var += 1 > end Both variables (button and global_variable) are local to the advance method and are not the same as the local variables button and global_variable defined below. This is the source of your problem. > global_var = 0 > > root = TkRoot.new(:title=>'Example') > button = TkButton.new(root) { > text "button" > } > button.pack("side"=>"right", "fill"=>"y") > tick = proc{|aobj| > advance > } > timer = TkTimer.new(250, -1,tick ) > timer.start(0) > > Tk.mainloop() > So how I should call own methods? One solution is to use real global variables. #!/usr/bin/env ruby require "tk" def advance $button.text = $global_var.to_s $global_var += 1 end $global_var = 0 root = Tk.root root.title('Example') win_w, win_h, win_y = 150, 50, 50 win_x = (root.winfo_screenwidth - win_w) / 2 root.geometry("#{win_w}x#{win_h}+#{win_x}+#{win_y}") root.resizable(false, false) $button = TkButton.new(root, :text => "button") $button.pack(:fill => :both, :expand => true) TkTimer.new(250, -1) { advance }.start Tk.mainloop Another, and IMO better, solution is take advantage of Ruby being object-oriented. #!/usr/bin/env ruby require "tk" class MyButton def initialize(parent) @count = 0 @me = TkButton.new(parent).pack(:fill => :both, :expand => true) TkTimer.new(250, -1) { advance }.start end def advance @count += 1 @me.text(@count.to_s) end end root = Tk.root root.title('Example') win_w, win_h, win_y = 150, 50, 50 win_x = (root.winfo_screenwidth - win_w) / 2 root.geometry("#{win_w}x#{win_h}+#{win_x}+#{win_y}") root.resizable(false, false) MyButton.new(root) Tk.mainloop Regards, Morton