Morton Goldberg
8/21/2007 6:45:00 PM
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()
<snip>
> So how I should call own methods?
One solution is to use real global variables.
<code>
#!/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
</code>
Another, and IMO better, solution is take advantage of Ruby being
object-oriented.
<code>
#!/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
</code>
Regards, Morton