Reputation: 3545
Here I have a simple python app using Tkinter
from Tkinter import *
def draw(i,j):
button[(i,j)]['text'] = 'X'
if __name__ == '__main__':
root = Tk()
root.title('Number Recognation')
button = {}
for i in range(2):
for j in range(2):
button[(i,j)] = Button(width = 3,command = lambda: draw(i,j))
button[(i,j)].grid(row = i,column = j)
root.mainloop()
I want to make a little program where are four blank buttons and where you push one of them, it changes it's text to "X". So when I write this program using of for
loops, it is not working correctly, on click it changes this button which stands in the second row and the second column. If I write without for
loops
button[(0,0)] = Button(width = 3,command = lambda: draw(0,0))
button[(0,0)].grid(row = 0,column = 0)
button[(0,1)] = Button(width = 3,command = lambda: draw(0,1))
button[(0,1)].grid(row = 0,column = 1)
button[(1,0)] = Button(width = 3,command = lambda: draw(1,0))
button[(1,0)].grid(row = 1,column = 0)
button[(1,1)] = Button(width = 3,command = lambda: draw(1,1))
button[(1,1)].grid(row = 1,column = 1)
here is not a problem.
Really I want to use for loop, because I am going to have many buttons here.
Upvotes: 3
Views: 72
Reputation: 369074
i
, j
is bound when the callback is called, not when the callback is created. You can use default parameter to avoid the late binding problem.
for i in range(2):
for j in range(2):
button[(i,j)] = Button(width = 3,command = lambda i=i, j=j: draw(i,j)) # <---
button[(i,j)].grid(row = i,column = j)
Upvotes: 3