tkinter questions: behavior of StringVar, etc

Scott David Daniels Scott.Daniels at Acm.Org
Sun Mar 29 18:49:07 EDT 2009


Alan G Isaac wrote:
>> Alan asked:
>>> - Why does a Variable need a master? - If s is a StringVar instance, 
>>> why is   str(s) its name rather than its value?
> 
> On 3/29/2009 2:46 PM Scott David Daniels apparently wrote:
>> The answer to that, grasshopper, lies in the answer to the question, 
>> "What are StringVars designed to do?"  StringVars, and IntVars, and 
>> ... are elements to receive, hold, and propagate changes to values 
>> that will produce effects in the programs behavior or display.  I find 
>> IntVars easier to explain, since you get values for numbers lots of 
>> ways.  If a slider updates an IntVar, a signal must reach anything 
>> "interested" in the value of that IntVar.  For example, you have a 
>> rectangle, and a display of its height, width, area, and aspect ratio. 
>> If you change the height or the width, the area and aspect ratio need 
>> updating (as well as the value in the height or width).
> 
> In short, a Variable can have observers.  My question does
> not lie here.  At least, you have not persuaded me that it does.

But the answers to your questions lie here.  (1) An XxxVar is something
much different than its current contents -- it is an addressable point
in a web of interacting events.  The value currently in the XxxVar is
(in many ways) the least interesting thing about it.  If you created
the XxxVar before initializing the event system, there would have to be
a funny dance done when that event system got initialized: it would have
to run around and find all of the XxxVars and associate them with the
event system.  Also, the XxxVar code would have to know how to behave
when its value is set before the event system is started (as many things
start initialized).

> I take this to be the core of your argument: that a Variable
> cannot signal to a widget until the event mechanism is up
> and running.  But of course if you create e.g. a Frame, the
> "root" is automagically created.  So I do not understand
> your reasoning.
Right.  Tkinter could have been built to make a root at the
first instantiation of a StringVar or IntVar, but it wasn't.
Answering your why is a bit like answering the "Why did Picasso
choose primarily blue in his Blue Period, rather than green?"

> To elaborate, where could things go wrong if I could
> instantiate a Variable without first instantiating a Tk root
> object? .... [S]uppose I want to associate an ``Entry`` with
 > a ``StringVar``. If I have not already created a root,
 > I would have to create the ``Entry`` first (which
 > auotmagically creates the root) and then the ``StringVar``,
 > but what is the payoff from this restriction?

Hmmm -- where cvould things go wrong --- segment fault?
what happens when you call code that hasn't had the setup run?
The initialization of the XxxVar to some fixed value is the first
event generated by that XxxVar.  The XxxVar code calls the event
system saying 'blahblah' has been set to 0 or whatever.  Once the
event system is running, it can ignore this as nobody (no other
code such as an Entry instance) has expressed an interest.  Before
then the data structures may not be in a safe state.  What happens
to your TV when you change the channel before turning it on?

> Just to be clear, I am not so presumptuous as to try to
> challenge the design.  I am trying to understand it.
But you are trying to understand it by asking why it is
not different from how it currently is.  Sometimes the
answer is "because it is the way it is."

> PS If you were also offering an answer to the second question,
> I missed it altogether, but although it is perhaps slightly
> less obvious than with a StringVar, I would ask the same
> basic question of an IntVar: why does it not behave more
> like an int?  E.g., why is ``int(IntVar(value=5))`` an
> error, or at least, why is ``str(IntVar(value=5))`` the name
> of the IntVar instead of '5'?

I think I answered that above, but here's another try before I'm
done with you:  Printing a StrVar is not the same as printing the
contents of a StrVar.  Having "magic" conversions happen for you
when they can be useful simply allows you to make mistakes about
what things are what.  Python has a set of design principles
available through "import this", the second (Explicit is better
than implicit) and twelfth (In the face of ambiguity, refuse the
temptation to guess) apply here.  int((1,)) is not 1, it is a failure.
str(("test",)) is "('test',)", not 'test'.

--Scott David Daniels
Scott.Daniels at Acm.Org






More information about the Python-list mailing list