how do I pass self.selected(i)? – Python

Question:

from tkinter import *

class App:
    def __init__(self, master):
        frame = Frame(master)
        frame.grid()
        self.grid_data_table = ["NONE"]
        self.D_Text = "    "
        self.a = 0
        self.b = 0

        for i in range(1,100 + 1):
            self.grid_data_table.extend([i])
            self.grid_data_table[i] = Button(frame, text=self.D_Text, font="bold", command=lambda: self.selected(i))

            self.a = self.a + 1
            self.grid_data_table[i].grid(row=self.b, column=self.a)
            #self.grid_data_table[i]["text"] = str(i) # testing only

            if self.a == 10:
                self.b = self.b + 1
                self.a = 0




    def selected(self, num):
        print("Loaded Button:", num)

root = Tk()
app = App(root)
root.mainloop()

anyhow, When I run this, I get the grid of 100 buttons in a 10×10 square, just the way I want, but the issue is command=self.selected(i) seems to make all of the buttons do self.selected(100) and no 1,2,3,4… 100. am I doing something wrong here?

I wanted to use a “list” or “array” to do this because it is so much easier than writing 100 buttons out.

Asked By: FBspitty

||

Answers:

You can do the following

command=lambda i=i: self.selected(i)

You are creating what is called a closure and when your command executes it captures the value of i at that point (hence always 100), not when the button is created. If you assign i to another local variable then you capture its value at the point the Button is created.

Answered By: Paul Rooney

Try changing this line,

self.grid_data_table[i] = Button(frame, text=self.D_Text, font="bold", command=lambda: self.selected(i))

to

self.grid_data_table[i] = Button(frame, text=self.D_Text, font="bold", command=lambda i=i: self.selected(i))

The problem is the current code is closing over the variable i, so in each command it is equal to whatever it is set to outside the function. Adding the i=i before creates a locally scoped variable i which does not change as the loop iteration continues.

Answered By: sberry