John Henderson
John Henderson

Reputation: 9

How can I identify the button I click on the grid with a nested list of names? Python - .Tkinter

I currently have a grid of buttons with rows and columns(using a for loop) and want to be able to click one of these buttons and it return, for instance, a1 is clicked.

import tkinter as tk
#list I need that attributes grid index to button name
#seats=[["A", "a1", "a2", "a3", "a4", "a5"]["B", "b1", "b2", "b3", "b4", "b5"]["C", "c1", "c2", "c3", "c4", "c5"], ["D", "d1", "d2", "d3", "d4", "d5"]]

def make_buttons():

    for r in range(10):
        for c in range(10):
            btn = tk.Button(root, text="Empty")
            btn['command'] = lambda c=c, r=r, b=btn:red_click(c, r, b)
            btn.grid(row=r,column=c)

def red_click(c, r, btn):
    print(btn, "clicked!")
    btn.configure(bg="red")


root = tk.Tk()

make_buttons()

root.mainloop()

I expect it to return to me which button was clicked. I've tried making it so that it prints it, but I can't certainly identify buttons as it shows, i.e., .!Button25 clicked!

Upvotes: 0

Views: 207

Answers (2)

mhawke
mhawke

Reputation: 87134

You can bind values to arbitrary attributes on the Button object. Then you can retrieve that value using an attribute lookup.

Also, it would be better to use the seating plan held in the seats list to create the buttons. You can use enumerate() to help iterate over the values while still having access to the indices that you need for the grid:

import tkinter as tk

seats= [["A", "a1", "a2", "a3", "a4", "a5"],
        ["B", "b1", "b2", "b3", "b4", "b5"],
        ["C", "c1", "c2", "c3", "c4", "c5"],
        ["D", "d1", "d2", "d3", "d4", "d5"]]

def make_buttons():
    for r, row in enumerate(seats):
        for c, seat in enumerate(row[1:]):        # N.B. skip first element
            btn = tk.Button(root, text="Empty")
            btn.name = seat                       # arbitrary attribute on Button object
            btn['command'] = lambda c=c, r=r, b=btn:red_click(c, r, b)
            btn.grid(row=r,column=c)

def red_click(c, r, btn):
    print(btn.name, "clicked!")
    btn.configure(bg="red")

root = tk.Tk()
make_buttons()
root.mainloop()

For many objects Python lets you create "arbitrary" attributes on the object from outside of the class itself. E.g.

class C:
    pass

>>> c = C()
>>> c.whatever
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: C instance has no attribute 'whatever'
>>> c.whatever = 'hi there'
>>> c.whatever
'hi there'

Upvotes: 1

furas
furas

Reputation: 143187

In red_click you have pair r,c so you can get seats[r][c]

Upvotes: 1

Related Questions