Tkinter button command curiousity

Hans-Joachim Widmaier hjwidmaier at web.de
Thu Jan 8 16:39:39 EST 2004


Am Thu, 08 Jan 2004 15:08:56 -0500 schrieb mksql:

> New to Tkinter. Initially, I had some code that was executing button commands at
> creation, rather than waiting for user action. Some research here gave me a
> solution, but I am not sure why the extra step is necessary.

There is no "extra step," as you will see.

> This causes the "graph" function to execute when the button is created:
> 	Button(root, text='OK', command=graph(canvas)))

Here you are calling graph() immediatly and bind the result to the
parameter 'command' - most likely not the intended effect (as you
observed).

> However, this waits until the button is pressed (the desired behavior):
> 	def doit():
> 	     graph(canvas)
> 	Button(root, text='OK', command=doit))

Here you bind the function object 'doit' to the command parameter, which
will then be called when the button is clicked on. You could also bind
the 'graph' function object to command, but then you cannot give it your
argument 'canvas'. Lambdas are often used to overcome this problem, but
your 'doit' local function essentially amounts to the same.

> Functionally, what is the difference? Why do I need to create a
> function, to call a function, simply to make a button command wait until
> pressed? Is there a better method?

The difference is, again:

def function(blah)
    pass

Here, 'function(x)' calls the function, whereas 'function' (without the
parenthethis) is just the function object (which can be bound to a name
which then later can be used to call it).

A better method? Would you call this better?

    Button(root, text='OK', command=lambda event, cvs=canvas: graph(cvs))

Usually, Tkinter programs employ a class that implements the GUI. Here you
can keep your canvas in a class attribute and use it in the callback
method:

class myGUI(Frame):
     # ....
         self.canvas = Canvas(root, ...)
         Button(root, text='OK', command=self.graph)

     def graph(self, event=None):
         # Use self.canvas

Hope this helps,
Hans-Joachim





More information about the Python-list mailing list