Odd behavior in Python/Tkinter?

L

Lie

Inspect the following code:

--- start of code ---
import Tkinter as Tk
from Tkconstants import *

root = Tk.Tk()

e1 = Tk.Entry(root, text = 'Hello World')
e2 = Tk.Entry(root, text = 'Hello World')

e1.grid(row = 1, column = 1)
e2.grid(row = 2, column = 1)

e1.insert(END, 'Hello Python')

root.mainloop()

--- end of code ---

What do you expect the result should be?
a. Two textboxes: One contains 'Hello Python', the other 'Hello World'
b. Two textboxes: Both containing 'Hello World'
c. Two textboxes: Both containing 'Hello Python'
d. Two textboxes: Both empty
e. Don't know

Check your guess with your Python 2.5.1 (AFAIK, the latest version at
the moment of writing)
 
F

Fredrik Lundh

Lie said:
Inspect the following code:

--- start of code ---
import Tkinter as Tk
from Tkconstants import *

root = Tk.Tk()

e1 = Tk.Entry(root, text = 'Hello World')
e2 = Tk.Entry(root, text = 'Hello World')

the "text" (or "textvariable") option to the Entry widget is the name of
the Tcl variable that should hold the result.

to get something that's a bit more usable from Python, use a StringVar
instance instead. alternatively, use the "get" method to fetch text
from the widget, and the "insert" method to add text to it.

also see:

http://effbot.org/tag/Tkinter.entry

</F>
 
S

Simon Forman

Inspect the following code:

--- start of code ---
import Tkinter as Tk
from Tkconstants import *

root = Tk.Tk()

e1 = Tk.Entry(root, text = 'Hello World')
e2 = Tk.Entry(root, text = 'Hello World')

e1.grid(row = 1, column = 1)
e2.grid(row = 2, column = 1)

e1.insert(END, 'Hello Python')

root.mainloop()

--- end of code ---

What do you expect the result should be?
a. Two textboxes: One contains 'Hello Python', the other 'Hello World'
b. Two textboxes: Both containing 'Hello World'
c. Two textboxes: Both containing 'Hello Python'
d. Two textboxes: Both empty
e. Don't know

Check your guess with your Python 2.5.1 (AFAIK, the latest version at
the moment of writing)



Huh. I got C (using python 2.4.3 on Ubuntu Linux..)

That ain't right.
 
L

Lie

the "text" (or "textvariable") option to the Entry widget is the name of
the Tcl variable that should hold the result.

to get something that's a bit more usable from Python, use a StringVar
instance instead.  alternatively, use the "get" method to fetch text
from the widget, and the "insert" method to add text to it.

also see:

     http://effbot.org/tag/Tkinter.entry

</F>

I realized that 'text' isn't a normally valid arguments for Entry (and
I'm also aware about the insert, get, etc), but what makes me creep is
the fact that the Entry's value would mirror each other if they're set
to the same 'text' value (Actually, I'm interested on how they
implement the Tkinter's/Tcl/Tk Entry box that this kind of behavior
could ever possibly exist [I started Pythoning just two weeks ago, so
my knowledge on its internals is quite limited]).
 
F

Fredrik Lundh

I realized that 'text' isn't a normally valid arguments for Entry (and
I'm also aware about the insert, get, etc), but what makes me creep is
the fact that the Entry's value would mirror each other if they're set
to the same 'text' value

note that you've set the "textvariable" option, not the "text" option.
Tk allows you to abbreviate option names.

and since you've set the "textvariable" option for both widgets to the
same variable, you've asked them both to display the same variable.
Tkinter just does what you've asked it to.

this is no different from using a Tkinter variable to display the same
value in a number of radiobutton widgets.

</F>
 
L

Lie

note that you've set the "textvariable" option, not the "text" option.
Tk allows you to abbreviate option names.

and since you've set the "textvariable" option for both widgets to the
same variable, you've asked them both to display the same variable.
Tkinter just does what you've asked it to.

this is no different from using a Tkinter variable to display the same
value in a number of radiobutton widgets.

</F>

But an expression (e.g. string) is NOT a variable. It's fine if the
value mirrored when I set the textvariable conf to the same variable,
but in this case I'm setting them to the same expression (e.g. string).
 
L

Lie

But an expression (e.g. string) is NOT a variable. It's fine if the
value mirrored when I set the textvariable conf to the same variable,
but in this case I'm setting them to the same expression (e.g. string).

On the other hand, the oddness multiplied since the value replication
doesn't happen if I set the textvariable to a variable. So, why is it?
A checkbox/optionbox value replication works if they're set to a
variable (I don't know if they're set to an expression) but Entry's
value replication works only if they're set to expression not variable.
 
F

Fredrik Lundh

Lie said:
But an expression (e.g. string) is NOT a variable.

in this case, it is. I don't know if it's worth spending more time on
this, since you're not listening, but let's make one more attempt.

for the Entry widget, the "textvariable" argument, if given, identifies
an *internal* Tkinter variable (managed by the embedded Tcl inter-
preter, not Python). changes to this variable will be reflected in the
widget, and changes to the widget will be reflected in the variable.

the *usual* way to create such a variable is to use StringVar, and leave
it to Tkinter to come up with an internal variable name, but you can
refer to any Tcl variable; if it doesn't exist, it's created.

in your example, you told both widgets to use the same internal
variable. you can do the same thing with a StringVar:

var = Tk.StringVar()

e1 = Tk.Entry(root, textvariable = var)
e2 = Tk.Entry(root, textvariable = var)

doing this has the advantage that you can access the internal variable
via the StringVar object (held in the Python variable named "var"), but
at the Tkinter level, it's exactly the same thing. changes to the
variable will be reflected in both widgets, and changes to *either*
widget will be reflected in the variable, and therefore also in the
other widget.
> On the other hand, the oddness multiplied since the value replication
> doesn't happen if I set the textvariable to a variable.

sure does, if you use the same internal variable for both widgets.

</F>
 
L

Lie

in this case, it is.  I don't know if it's worth spending more time on
this, since you're not listening, but let's make one more attempt.

Sure I'm listening (well, actually I'm reading), but please spare me
since I can't understand what you meant in the previous posts (I'm
just starting Python, and yesterday was my first introduction to
Tkinter/Tk/Tcl). Everyone has their own newbie moments...
for the Entry widget, the "textvariable" argument, if given, identifies
an *internal* Tkinter variable (managed by the embedded Tcl inter-
preter, not Python).  changes to this variable will be reflected in the
widget, and changes to the widget will be reflected in the variable.

That clears things up. I never realized that we can even specify the
name for the Tcl's variable, setting its values is a behavior, but
setting its name is... some kind of incomplete encapsulation (well its
understandable, complete encapsulation is never a Pythonic thing and
proper ways to keep the encapsulation is available [through
StringVar]).
the *usual* way to create such a variable is to use StringVar, and leave
it to Tkinter to come up with an internal variable name, but you can
refer to any Tcl variable; if it doesn't exist, it's created.

in your example, you told both widgets to use the same internal
variable.  you can do the same thing with a StringVar:

     var = Tk.StringVar()

     e1 = Tk.Entry(root, textvariable = var)
     e2 = Tk.Entry(root, textvariable = var)

doing this has the advantage that you can access the internal variable
via the StringVar object (held in the Python variable named "var"), but
at the Tkinter level, it's exactly the same thing.  changes to the
variable will be reflected in both widgets, and changes to *either*
widget will be reflected in the variable, and therefore also in the
other widget.


 > On the other hand, the oddness multiplied since the value replication
 > doesn't happen if I set the textvariable to a variable.

sure does, if you use the same internal variable for both widgets.

After reading your post, I realized the reason why it doesn't
replicate was because I set the variable to an empty string, which
doesn't initialize the textvariable.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
VetaMcRae
Top