Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tkinter. Create multiple buttons with "different" command function

first of all, sorry for the title, I couldn't find a better one.

The following code is a minimalized version of a problem I have in my Python program (I am a newbie btw.).

def onClick(i):
    print "This is Button: " + str(i)
    return

def start():
    b = [0 for x in range(5)]
    win = Tkinter.Tk()
    for i in range(5):
        b[i] = Tkinter.Button(win,height=10,width=100,command=lambda : onClick(i))
        b[i].pack()
    return

What it does: Whatever Button I click, it says "This is Button: 4".

What I want: First button should say "This is Button: 0" and so on.

Is this a wanted behaviour of Python? And if the answer is yes, why is that so? How can I fix it?

On the other hand, this works fine:

def start():        
    x = [0 for x in range(5)]
    for i in range(5):
        x[i] = lambda:onClick(i)
        x[i]()
    return
like image 759
kaan Avatar asked Nov 29 '14 02:11

kaan


People also ask

Can Tkinter buttons have multiple commands?

We can perform a certain action with the help of a Button that encapsulates the function and the objects. However, there might be cases when we want to perform multiple operations with a single button. This can be achieved by defining the lambda functions which target multiple events or callback in the application.

How do you make multiple buttons in Python?

Build A Paint Program With TKinter and Python Let us suppose that we want to create multiple buttons, each with different commands or operations defined in it. We have to first initialize the Button inside a for loop. The iterator will return the object for which multiple instances of the button will be created.

What is Tk () in Tkinter Python?

The tkinter package (“Tk interface”) is the standard Python interface to the Tcl/Tk GUI toolkit. Both Tk and tkinter are available on most Unix platforms, including macOS, as well as on Windows systems.


1 Answers

Use default parameter to avoid late-binding issue (Otherwise i is bound when the lambda function is called, not when it is created):

def start():
    buttons = []
    win = Tkinter.Tk()
    for i in range(5):
        b = Tkinter.Button(win, height=10, width=100, command=lambda i=i: onClick(i))
        b.pack()
        buttons.append(b)
like image 56
falsetru Avatar answered Sep 24 '22 22:09

falsetru