Tkinter: Canvas.tag_bind() not working as expected

Hello all,

I’ve got a little piece of code here and I can’t for the life of me work out why it’s not working as I expect. I know there are other ways to achieve this so (respectfully) I’m not looking for alternatives.

def setColour(c):
    global colour
    colour = c

for i, j in ((1,'red'),(2,'green'),(3,'blue'),(4,'yellow'),(5,'black')):
    canvas.tag_bind(i, '<Button-1>', lambda _: setColour(j))

It works in a fashion; each canvas item for which the event is bound to the handler does invoke setColour() when clicked, however the value of colour is always set to 'black', as revealed by the print() statement.

Any help is much appreciated as always!

Try changing the one line to:
canvas.tag_bind(i, '<Button-1>', lambda _, color=j: setColour(color))

I’m not great at lambdas, but I think that you need to capture the variable at lambda definition, rather than just reference it.

1 Like

Bingo! thanks for that.

I’d tried:

lambda _, j: setColour(j)

but of course that didn’t work because the event object is passed in as _ implicitly, while j is not.

Many thanks!

1 Like

Tkinter code is the only place I use lambdas extensively, and for some reason it always takes several goes at it to get the right syntax!

This is an extremely commonly mentioned issue, that especially comes up in Tkinter code. See:

1 Like