-2

I'm trying to create a column of label containing images in a for loop, I want them to have a specific command when I do a right click a left click on the image, I searched a solution and found this question. The answer of BrenBarn worked well only if i use a button. But the event Button-1, isn't returning any value that can differentiate one label from another.

WORKING :

active="red"
default_color="white"

def main(height=5,width=5):
  for x in range(width):
    for y in range(height):
      btn = tkinter.Button(frame, bg=default_color)
      btn.grid(column=x, row=y, sticky=N+S+E+W)
      btn["command"] = lambda btn=btn: click(btn)

  for x in range(width):
    Grid.columnconfigure(frame, x, weight=1)

  for y in range(height):
    Grid.rowconfigure(frame, y, weight=1)

  return frame

def click(button):
    print(button)
    if(button["bg"] == active):
        button["bg"] = default_color
    else:
        button["bg"] = active

w= main(10,10)

NOT WORKING :

active="red"
default_color="white"

def main(height=5,width=5):
  for x in range(width):
    for y in range(height):
      btn = tkinter.Button(frame, bg=default_color)
      btn.grid(column=x, row=y, sticky=N+S+E+W)
      btn.bind("<Button-1>", lambda btn=btn: click(btn))

  for x in range(width):
    Grid.columnconfigure(frame, x, weight=1)

  for y in range(height):
    Grid.rowconfigure(frame, y, weight=1)

  return frame

def click(button):
    print(button)
    if(button["bg"] == active):
        button["bg"] = default_color
    else:
        button["bg"] = active

w= main(10,10)
Nothex
  • 13
  • 5
  • 2
    The concept is the same, no matters it is for `command` option of `` event binding. – acw1668 Jul 03 '22 at 15:14
  • but when I do the same it's not working – Nothex Jul 04 '22 at 16:03
  • The function for event binding requires an event argument: `lambda e, btn=btn: click(btn)`. – acw1668 Jul 04 '22 at 22:43
  • But for your case, `btn` argument is not necessary as the first event argument already has an attribute `widget` which is the widget that triggers the event: `lambda e: click(e.widget)`. – acw1668 Jul 04 '22 at 23:04

1 Answers1

0

The signatures of the functions required for command option of a button and event binding are different. Function for command option expects no argument, whereas function for event binding expects an argument, the Event object.

Therefore the following line:

btn.bind("<Button-1>", lambda btn=btn: click(btn))

should be as below:

# added the required argument "e"
btn.bind("<Button-1>", lambda e, btn=btn: click(btn))

However, for your case the btn argument is not necessary because the Event object has an attribute widget which is the widget that triggers the event:

# used e.widget
btn.bind("<Button-1>", lambda e: click(e.widget))
acw1668
  • 40,144
  • 5
  • 22
  • 34