Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tkinter creating buttons in for loop passing command arguments

Tags:

python

tkinter

I am trying to create buttons in tkinter within a for loop. And with each loop pass the i count value out as an argument in the command value. So when the function is called from the command value I can tell which button was pressed and act accordingly.

The problem is, say the length is 3, it will create 3 buttons with titles Game 1 through Game 3 but when any of the buttons are pressed the printed value is always 2, the last iteration. So it appears the buttons are being made as separate entities, but the i value in the command arguments seem to be all the same. Here is the code:

def createGameURLs(self):     self.button = []     for i in range(3):         self.button.append(Button(self, text='Game '+str(i+1),                                   command=lambda: self.open_this(i)))         self.button[i].grid(column=4, row=i+1, sticky=W)  def open_this(self, myNum):     print(myNum) 

Is there a way to get the current i value, each iteration, to stick with that particular button?

like image 765
Marcel Avatar asked Jun 02 '12 19:06

Marcel


People also ask

Can Tkinter buttons have multiple commands?

The Tkinter button has only one command property so that multiple commands or functions should be wrapped to one function that is bound to this command .


1 Answers

Change your lambda to lambda i=i: self.open_this(i).

This may look magical, but here's what's happening. When you use that lambda to define your function, the open_this call doesn't get the value of the variable i at the time you define the function. Instead, it makes a closure, which is sort of like a note to itself saying "I should look for what the value of the variable i is at the time that I am called". Of course, the function is called after the loop is over, so at that time i will always be equal to the last value from the loop.

Using the i=i trick causes your function to store the current value of i at the time your lambda is defined, instead of waiting to look up the value of i later.

like image 80
BrenBarn Avatar answered Oct 10 '22 22:10

BrenBarn