I'm trying to use Python objects as wrappers for Tk canvas items. For instance:
class PlayingCard:
def __init__(self, item):
self.item = item
aceOfSpades = PlayingCard(canvas.create_image((coordinates), image = PhotoImage(aceofspades.gif)))
print aceOfSpades.item
>>> <canvas item id>
This way, if I need to manipulate a canvas item, I can reference it by an object:
aceOfSpades.item.move(dx, dy)
So, the problem is that I have lots of objects (52, in fact), each with their own self.item which refers to a canvas image item, and I want to iterate over the objects and create event bindings for their canvas items if the object meets certain conditions. This is my solution (pseudo pycode):
def event_handler(card):
card.attribute = updated_value
for card in [list of card objects]:
if card.attribute == test_condition:
canvas.tag_bind(
card.item, #this is the item id stored in the PlayingCard.item variable
<Event Sequence>,
lambda x: event_handler(card)
)
The problem is that, after the iteration is complete, all the event bindings pass the same argument to the event handler.
In other words, I wanted to pass the card object to the event handler as an argument, so that event handler would have access to the card object when an event occurs corresponding to the card's object.item canvas item. However, what this code does instead is pass the same argument (i.e. card object) to the event handler regardless of canvas item. In code, this means that if the event sequence is a click, then clicking on any card canvas item calls the function event_handler(<last card object in iteration>)
, whereas I want clicking on a canvas item to call event_handler(<corresponding card object>)
.
Am I making sense? I don't understand why this approach doesn't yield the results I want it to.