473,398 Members | 2,165 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

Tkinter button command curiousity

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.

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

However, this waits until the button is pressed (the desired behavior):
def doit():
graph(canvas)
Button(root, text='OK', command=doit))
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?

Jul 18 '05 #1
2 3984
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
Jul 18 '05 #2
In article <sr********************************@4ax.com>,
mk***@yahoo.com wrote:
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.

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

However, this waits until the button is pressed (the desired behavior):
def doit():
graph(canvas)
Button(root, text='OK', command=doit))
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?


This is a standard issue with callback functions.

Suppose you have a trivial function foo:
def foo(arg1, arg2):
print "foo(%r, %r)" % (arg1, arg2)

To use foo as a callback function you need to pass it *AS* a function:
anobj(callback=foo)
and that callback had better include the necessary args. If you try to
specify args when specifying the callback, you end up passing the RESULT
of the function (the mistake):
anobj(callback=foo("bar", "baz"))
foo gets called just once, when creating an obj, and callback gets set
to None (the result of calling foo with args "bar" and "baz"). Later
when anobj wants to call the callback, it has nothing to call!

There are various solutions. The one you chose is excellent. Others
include:

-Use lambda to avoid creating a named function, but I find this much
less readable.

- Use a "currying" class; this takes an existing function and
pre-defined arguments and returns a new function that you use as your
callback. A good example of such a class is:
<http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549>. It's a
nice thing to have around if you do a lot of callbacks, but otherwise I
find your solution the most readable.

- If your widget is a class, you may be able to pass your data as class
instances. This works if there is only one obvious canvas to graph. For
example:
class mywdg(Tkinter.Frame):
def __init__(self, master, etc.)
Tkinter.Frame.__init__(self, master)
self.canvas = Tkinter.Canvas(self,...)
self.button = Tkinter.Button(self, command=self.graph)
...
def graph(self):
# do stuff to self.canvas

- As a more sophisticated variant, if you several canvases to graph, and
want one button for each, you could make the canvases into objects
(similar to the example above) and pass the right one to the button,
e.g.:
for cnvsobj in listofobj:
abutton = Tkinter.Button(self, command= cnvsobj.graph)

- Also note that a very few Tkinter functions (such as after) allow you
to specify a function and additional arguments.

-- Russell
Jul 18 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Andrew Gregory | last post by:
Could someone help me out with these few lines of code: I would like to know why the Quit button in this application removes the buttons and causes "Quitting" to be printed, but does not close the...
3
by: srijit | last post by:
Hello, Any idea - why the following code crashes on my Win 98 machine with Python 2.3? Everytime I run this code, I have to reboot my machine. I also have Win32all-157 installed. from Tkinter...
2
by: Paul A. Wilson | last post by:
I'm new to Tkinter programming and am having trouble creating a reusable button bar... I want to be able to feed my class a dictionary of button names and function names, which the class will make....
0
by: Stewart Midwinter | last post by:
I have a Tkinter app running on cygwin. It includes a Test menu item that does nothing more than fetch a directory listing and display it in a Toplevel window (I'd use a tkMessageBox showinfo...
1
by: C D Wood | last post by:
To whom this may concern, Below is the source code, which demonstrates a problem I am having making a GUI for my python project work. 'table.txt' is a file that is read from the same folder....
1
by: Michael Yanowitz | last post by:
Hello: Below I have included a stripped down version of the GUI I am working on. It contains 2 dialog boxes - one main and one settings. It has the following problems, probably all related, that...
6
by: Eric_Dexter | last post by:
Instead of creating my buttons and waiting for me to press them to execute they are executing when I create them and won't do my callback when I press them.. thanks for any help in advance ...
2
by: skanemupp | last post by:
so my little calculator works perfectly now. just having some trouble with the layout. this whole tkinter-thing seems to be more tricky than it should be. how can i make the 4 column of buttons...
3
by: J-Burns | last post by:
Hello. Im a bit new to using Tkinter and im not a real pro in programming itself... :P. Need some help here. Problem 1: How do I make something appear on 2 separate windows using Tkinter? By...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.