Tkinter Newbie Question

R

robbie

Hello Group,

I'm a programmer with many years experience, but am new to Python and
to object oriented programming. I'm working my way through a book on
Python, and have been tweaking the examples to see what they do. I've
run into a situation that I don't understand, though I expect it's
pretty simple for anyone more skilled than I am. Here's a snippet of
code:

This first example works. It creates three windows with a button in
each that prints a word when I press the button:

from Tkinter import *
root = Tk()

trees = [('The Larch!', 'light blue'),
('The Pine!', 'light green'),
('The Giant Redwood!', 'red')]

def salutation():
print "Something!"

for (tree, color) in trees:
win = Toplevel(root)
win.title('Sing...')
win.protocol('WM_DELETE_WINDOW', lambda:0)
win.iconbitmap('py-blue-trans-out.ico')
msg = Button(win, text='Write Something', command=salutation)
msg.pack(expand=YES, fill=BOTH)
msg.config(fg='black', bg=color, font=('times', 30, 'bold
italic'))

root.title('Lumberjack demo')
Label(root, text='Main window', width=30).pack()
Button(root, text='Quit All', command=root.quit).pack()
win.mainloop()

This second example doesn't work. The only difference is that I gave
the salutation function a parameter and tried to pass a string as the
parameter from the button. It appears to call the function once for
each window as they're being created, but doesn't do anything when the
buttons in the windows are pressed.

from Tkinter import *
root = Tk()

trees = [('The Larch!', 'light blue'),
('The Pine!', 'light green'),
('The Giant Redwood!', 'red')]

def salutation(j=""):
print j + " Something!"

for (tree, color) in trees:
win = Toplevel(root)
win.title('Sing...')
win.protocol('WM_DELETE_WINDOW', lambda:0)
win.iconbitmap('py-blue-trans-out.ico')
msg = Button(win, text='Write Something',
command=salutation(tree))
msg.pack(expand=YES, fill=BOTH)
msg.config(fg='black', bg=color, font=('times', 30, 'bold
italic'))

I figure there's something very basic I'm missing about passing a
parameter from a Tkinter widget to a function. Can anyone tell me what
I'm doing wrong?

Thank you so much!
Robbie in Montana
 
M

Marc 'BlackJack' Rintsch

This second example doesn't work. The only difference is that I gave
the salutation function a parameter and tried to pass a string as the
parameter from the button. It appears to call the function once for
each window as they're being created, but doesn't do anything when the
buttons in the windows are pressed.

from Tkinter import *
root = Tk()

trees = [('The Larch!', 'light blue'),
('The Pine!', 'light green'),
('The Giant Redwood!', 'red')]

def salutation(j=""):
print j + " Something!"

for (tree, color) in trees:
win = Toplevel(root)
win.title('Sing...')
win.protocol('WM_DELETE_WINDOW', lambda:0)
win.iconbitmap('py-blue-trans-out.ico')
msg = Button(win, text='Write Something',
command=salutation(tree))

You are calling the function here. Parenthesis after a callable like a
function means "call it *now*", so you are calling `salutation()` and bind
the *result* of that call to `command`. An idiomatic solution is to use a
``lambda`` function::

msg = Button(win,
text='Write Something',
command=lambda t=tree: salutation(t))

In Python 2.5 there's an alternative way with the `functools.partial()`
function:

from functools import partial

# ...

msg = Button(win,
text='Write Something',
command=partial(salutation, tree))

Ciao,
Marc 'BlackJack' Rintsch
 
R

robbie

Hi Mark,

Thank you so much for the help. I figured it was something pretty
simple like that. And I was also puzzled by the concept of the lambda
function, so now I know what they do too. I just tried it out, and it
works well.

Much appreciated,
Ciao back at you,
Robbie
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top