Search code examples
pythontkinter

Targetting a specific button in a list of frames in tkinter


I created a list of 9 frames in Tkinter, and each frame has a group of 9 buttons arranged as a grid:

if __name__ == '__main__': 
    window = tkinter.Tk()

    
    frame = []
    for i in range(9):
        f = tkinter.Frame(window, bg="red")
        frame.append(f)

        
        button = [[0,0,0],
                  [0,0,0],
                  [0,0,0]]
        for j in range(3):
            for k in range(3):
                button[j][k] = tkinter.Button(frame[i], text="yo", padx=2, pady=2, command=lambda x=i, y=j, z=k: change_value(x,y,z))
                button[j][k].grid(row=j,column=k)

So now, every frame[i] has 9 buttons ie button[j][k]. I am trying to target the text of a single button in a particular frame from the change_value() function. How do I capture this? frame[i].button[j][k]["text"] does not work. Is it possible to target a particular button in a frame?


Solution

  • It is because you initialize button in every iteration of the outer for loop. You need to change button to attribute of the frame as below:

    frame = []
    for i in range(9):
        f = tkinter.Frame(window, bg="red", padx=10, pady=10)
        f.pack()
        frame.append(f)
    
        # create attribute "button" in the frame
        f.button = [[0,0,0],
                    [0,0,0],
                    [0,0,0]]
        for j in range(3):
            for k in range(3):
                # use f.button instead of button
                f.button[j][k] = tkinter.Button(frame[i], text="yo", padx=2, pady=2, command=lambda x=i, y=j, z=k: change_value(x,y,z))
                f.button[j][k].grid(row=j,column=k)
    

    Then you can use frame[x].button[y][z] to access the required button.