Calling a sequence of commands with a sequence of Tkinter buttons
Steve Purcell
stephen_purcell at yahoo.com
Tue Feb 20 08:10:59 EST 2001
Martyn Quick wrote:
> MY ATTEMPT:
>
> from Tkinter import *
>
> ...
>
> for i in range(20):
> buttons.append(Button(root,text="Button "+`i`,command=f(i)))
> buttons[i].pack()
> # This doesn't work - it just prints 1,2,..,20 down the screen
> # immediately, since f(i) is called at the creation of the button.
Right, you found the problem; f() is called immediately. Instead, give
Tkinter a new function that takes no parameters and that can be called later:
for i in range(20):
def f_i(j=i):
f(j)
buttons.append(Button(root,text="Button "+`i`,command=f_i))
buttons[i].pack()
Of, if you prefer:
for i in range(20):
buttons.append(Button(root,text="Button "+`i`,
command=lambda j=i, f(j)))
buttons[i].pack()
It would perhaps be neater to solve this with a callable class instance than
with a default function argument:
class PrintNumberAction:
def __init__(self, i):
self.i = i
def __call__(self):
print i # or whatever
then:
for i in range(20):
action = PrintNumberAction(i)
buttons.append(Button(root,text="Button "+`i`,command=action))
buttons[i].pack()
Hope that helps.
-Steve
--
Steve Purcell, Pythangelist
Get testing at http://pyunit.sourceforge.net/
Get servlets at http://pyserv.sourceforge.net/
"Even snakes are afraid of snakes." -- Steven Wright
More information about the Python-list
mailing list