Updated Answer:
As @Thingamabobs pointed out, it's possible to get the button via e.widget
in button_Clicked
function via the event object e
. Thus, it's not necessary to pass the button object to the function.
def button_Clicked(e):
button = e.widget
# toggle between 'red' and default color
if button['bg'] != 'red':
button['bg'] = 'red'
else:
button['bg'] = 'SystemButtonFace'
for i in range(0, 8):
for j in range(0, 8):
bij = tk.Button(compFrame, width=10, height=4)
bij.grid(row=i, column=j, padx=5, pady=5)
bij.bind("<Button-1>", button_Clicked)
root.mainloop()
Old Answer:
- You need to bind the event inside the loop. Right now,
bij
is outside the loop, so it's only the last button.
- To make sure the event changes color for the correct button, you need to add an argument to
button_Clicked
- To change toggle the background color on each click, it's necessary to add a condition in
button_Clicked
def button_Clicked(e, button):
# toggle between 'red' and default color
if button['bg'] != 'red':
button['bg'] = 'red'
else:
button['bg'] = 'SystemButtonFace'
for i in range (0,8):
for j in range (0,8):
bij = tk.Button(compFrame, width = 10, height=4)
bij.grid(row = i, column = j, padx = 5, pady = 5)
bij.bind("<Button-1>", lambda event, bij=bij: button_Clicked(event, bij))
As @BryanOakley rightly point out, it's necessary to use the trick
lambda event, bij=bij: button_Clicked(event, bij)
to make sure the lambda closure uses the current bij
value in the loop.
Alternatively, it's possibly cleaner to use functools.partial
for the last line
from functools import partial
...
bij.bind("<Button-1>", partial(button_Clicked, button=bij))