0

I am having some trouble with the button widgets.

Here's my code. Basically, what I would like to do is to print "0,0" when I press the first button, print "0,1" when I press the second button and so on. But what happens is that it always prints "1,1", which are last values in my for loops. How could I fix that?

Thanks a lot for helping

from tkinter import *

def show(x,y):

    print(x,y)

root = Tk()

a = 0

for i in range(2):

    for j in range(2):
        Button(root, text=a, command=lambda:show(i,j)).grid(column=j, row=i)
        a += 1

root.mainloop()
Martijn Pieters
  • 963,270
  • 265
  • 3,804
  • 3,187
A.P.
  • 421
  • 1
  • 7
  • 17

1 Answers1

0

It is because of the closure property of Python. To fix this, change

Button(root, text=a, command=lambda:show(i,j)).grid(column=j, row=i)

to

def inner(i=i, j=j):
    Button(root, text=a, command=lambda:show(i,j)).grid(column=j, row=i)
inner()

We are just wrapping the values of i and j with a function. Since the function show is not executed immediately, it just accepts the values of the two variables i and j. So, all the buttons now, will have the same i and j and they will get the values which are at the end of the loop.

Now, by defining a new function, we are getting a default parameter of the same names i and j and we get the values of i and j at the particular moment. So, the current values will be retained.

thefourtheye
  • 221,210
  • 51
  • 432
  • 478