Q about tk buttons


#1

Hi guys, I have a little problem with the buttons in tk. I want to add 1
to
a variable when pushing a button but tk won’t let me.
Here some of my code:

require “tk”
var = TkVariable.new(0) #defining variable
var += 1 #making it a fixnum and adding 1

root = TkRoot.new()

label = TkLabel.new(:text=> var).pack()

button = TkButton.new(:text=> “Button”, :command=>proc{var += 1}).pack()

Tk.mainloop

Why can I use var += 1 outside of the button, when I can’t use it inside
it.

Please help me :S

Thanks in advance.


#2

From: “Jeppe J.” removed_email_address@domain.invalid
Subject: Q about tk buttons
Date: Wed, 12 Apr 2006 06:41:39 +0900
Message-ID:
removed_email_address@domain.invalid

Why can I use var += 1 outside of the button, when I can’t use it inside it.

It means “var = var + 1”.
“var + 1” returns 4, because TkVariable#+(obj) method expects
“numerical plus” when the arguemnt ‘obj’ is kind of Numeric.
And by setting the numeric value 4 to var, var losts the link
to the TkVariable object.

Therefore, for example,

var = TkVariable.new(0) #defining variable
var += 1 #making it a fixnum and adding 1

var.value = var + 1
or
var.numeric += 1

root = TkRoot.new()

label = TkLabel.new(:text=> var).pack()

label = TkLabel.new(:textvariable=>var).pack()

button = TkButton.new(:text=> “Button”, :command=>proc{var += 1}).pack()

button = TkButton.new(:text=> “Button”, :command=>proc{var.value = var +
1}).pack()
or
button = TkButton.new(:text=> “Button”, :command=>proc{var.numeric +=
1}).pack()


#3

Thanks that kind of worked, but how come that the variable still returns
0,
when I add

puts var.value

to my code, just before Tk.mainloop?

2006/4/12, Hidetoshi NAGAI removed_email_address@domain.invalid:


#4

From: “Jeppe J.” removed_email_address@domain.invalid
Subject: Re: Q about tk buttons
Date: Wed, 12 Apr 2006 17:41:38 +0900
Message-ID: removed_email_address@domain.invalid

Thanks that kind of worked, but how come that the variable still returns 0,
when I add

puts var.value

to my code, just before Tk.mainloop?

???

—< var-test1.rb >----------------------------------------
require “tk”
var = TkVariable.new(0) #defining variable
var += 1 #making it a fixnum and adding 1

root = TkRoot.new()

label = TkLabel.new(:text=> var).pack()

button = TkButton.new(:text=> “Button”, :command=>proc{var += 1}).pack()

puts var.value

Tk.mainloop

$ /usr/local/bin/ruby -v
ruby 1.8.4 (2006-04-06) [i686-linux]
$ /usr/local/bin/ruby var-test1.rb
var-test1.rb:11: undefined method `value’ for 1:Fixnum (NoMethodError)

—< var-test2.rb >----------------------------------------
require “tk”
var = TkVariable.new(0)
var.numeric += 1
label = TkLabel.new(:textvariable=>var).pack()
button = TkButton.new(:text=> “Button”, :command=>proc{var.numeric +=
1}).pack()
puts var.value
Tk.mainloop

$ /usr/local/bin/ruby -v
ruby 1.8.4 (2006-04-06) [i686-linux]
$ /usr/local/bin/ruby var-test2.rb
1
$


#5

Oh sorry I meant to say that it returns 1. If I click the button 29
times,
the label shows 30, but the value that was puts’ed is still 1.

2006/4/12, Hidetoshi NAGAI removed_email_address@domain.invalid:


#6

From: “Jeppe J.” removed_email_address@domain.invalid
Subject: Re: Q about tk buttons
Date: Thu, 13 Apr 2006 01:31:03 +0900
Message-ID: removed_email_address@domain.invalid

Oh sorry I meant to say that it returns 1. If I click the button 29 times,
the label shows 30, but the value that was puts’ed is still 1.

Because, callbacks are called in the event loop (Tk.mainloop).
If you need some help and tell me what you want,
I may be able to help you.


#7

Thanks. I want to write a Ruby/Tk version of my first program ever (at
that
time I wrote in Delphi). It’s basically a program that takes a random
number
between 0-20 and tells the user to guess it by writing the guess in an
entry
and then press the button.

require “tk”
#methods
def guess
if (guess.value == right_guess.value)
status.value = “Correct!”
else
number_of_guess.numeric += 1
status.value = “Sorry, no luck”
end
end
#variables
right_guess = TkVariable.new(rand(21))
number_of_guess = TkVariable.new(0)
guess = TkVariable.new()
status = TkVariable.new(“Entry your guess and press the button”)
#windows
root = TkRoot.new(:title=>“Number guess”)
#labels
lbl_guess =
TkLabel.new(:textvariable=>number_of_guess).pack(:side=>“top”,
:pady=>10)
lbl_status = TkLabel.new(:textvariable=>status).pack(:side=>“bottom”,
:pady=>10)
#entries
entry = TkEntry.new(:textvariable=>guess).pack(:side=>“top”, :pady=>10)
#buttons
button = TkButton.new(:text=>“Guess”,
:command=>proc{guess}).pack(:side=>“top”, :pady=>10)
root = Tk.mainloop

I think the only problem with my code now is that my button won’t run my
method guess. But I don’t know why right now, because it seems to me
that
the methods from the Pigbox example in the pickaxe are run this way. I’m
probably missing something.

2006/4/13, Hidetoshi NAGAI removed_email_address@domain.invalid:


#8

Hmmm… There are some problems.

From: “Jeppe J.” removed_email_address@domain.invalid
Subject: Re: Q about tk buttons
Date: Thu, 13 Apr 2006 22:33:18 +0900
Message-ID:
removed_email_address@domain.invalid

require “tk”
#methods
def guess
if (guess.value == right_guess.value)
status.value = “Correct!”
else
number_of_guess.numeric += 1
status.value = “Sorry, no luck”
end
end

Probably, you’ll want to refer local variables on main.
But those variables are out of scope in the method.
If arguments bothers you, you can use a Proc object instead of a method.

Next, please see here.

def guess
^^^^^
guess = TkVariable.new()
^^^^^

There is conflict of names.
So, “proc{guess}” refers the local variable.
If you want to call “guess” method, you must use “proc{guess()}”.

root = Tk.mainloop

Probably, the return value is not useful.

If I were you, I may write such like as the following.

require ‘tk’

right_guess = rand(21)
number_of_guess = TkVariable.new(0)

Tk.root.title(‘Number guess’)

TkLabel.new(:textvariable=>number_of_guess).pack(:side=>:top,
:pady=>10)

status = TkLabel.new(:text=>“Entry your guess and press the button”,
:width=>37).pack(:side=>:bottom, :pady=>10)

entry = TkEntry.new.pack(:side=>:top, :pady=>10)

guess_cmd = proc{
value = entry.value
if value.empty? || value.to_i != right_guess
number_of_guess.numeric += 1
status.text(‘Sorry, no luck’)
else
status.text(‘Correct!’)
end
}

button = TkButton.new(:text=>‘Guess’,
:command=>guess_cmd).pack(:side=>:top, :p\ady=>10)

entry.bind(‘Return’, proc{button.invoke})

Tk.mainloop


#9

Thank you that really cleared things up :slight_smile:

But I don’t understand this line though

entry.bind(‘Return’, proc{button.invoke})

It doesn’t seem to make any difference whether I include it in the
program
or not. I tried to read about it in the documentation, but I only
understood
that it had something to do with invoking the command of the button.

2006/4/14, Hidetoshi NAGAI removed_email_address@domain.invalid:


#10

I’m probably misunderstanding the question, but after reading this post
I wrote a quick ruby test script to see if I could increment a variable
using a tkbutton and it seemed to work for me. Here is the code I used.
(I don’t know if this is what you are trying to do though)

require ‘tk’

class Hi
@var = 1;

@b1 = TkButton.new(:text => “Click me”, :command => proc {puts @var;
@var += 1}).pack

def initialize
Tk.mainloop
end
end

h = Hi.new()

############the first batch of code I wrote didn’t have a class
definition, I changed it so I could see what it would look like inside
of a class, here is the original code

require ‘tk’

var = 1;

b1 = TkButton.new(:text => “Click me”, :command => proc {puts var; var
+= 1}).pack

Tk.mainloop


#11

From: “Jeppe J.” removed_email_address@domain.invalid
Subject: Re: Q about tk buttons
Date: Fri, 14 Apr 2006 22:16:49 +0900
Message-ID:
removed_email_address@domain.invalid

But I don’t understand this line though

entry.bind(‘Return’, proc{button.invoke})

It is an additional binding for ‘Return’ key press on the entry widget.
When input a number and hit ‘Return’, you’ll get the same result
as clicking the button.


#12

I apologize, the original message I wrote wrapped some of the code


#13

Ah ok, thanks.

Gary:
That is because the variable you use is a Ruby variable, but mine is a
Tk
variable.

2006/4/15, Hidetoshi NAGAI removed_email_address@domain.invalid: