1

I have a list:

StoreItems = random.sample(set(['sword','pickaxe','toothpick','hammer','torch','saw']), 5)

and additional lines which add those 5 strings chosen onto my canvas, and give them binds.

XBASE, YBASE, DISTANCE = 300, 320, 50
for i, word in enumerate(StoreItems):  
    canvas.create_text(
        (XBASE, YBASE + i * DISTANCE),
        text=word, activefill="Medium Turquoise", anchor=W, fill="White", font=('Anarchistic',40))

found = canvas.find_closest(XBASE, YBASE)
if found:
    canvas.itemconfig(found[0])
    canvas.bind('<1>', Buy)

The problem is I need to assign each word a different tag bind, and currently it is giving all the words the same bind. So I cant make clicking saw have a different result rather than clicking toothpick.

MattDMo
  • 100,794
  • 21
  • 241
  • 231
Daijoubu
  • 65
  • 1
  • 6
  • 1
    Possible duplicate of [How do I attach event bindings to items on a canvas using Tkinter?](http://stackoverflow.com/questions/2786877/how-do-i-attach-event-bindings-to-items-on-a-canvas-using-tkinter) – Tadhg McDonald-Jensen Mar 25 '16 at 19:48
  • I understand the use of tag.binds as shown of the above link. The problem is in the example I listed It is displaying all of the items in the list as one object. I need to give each item in the list a separate tag. I cant to that when they are together as one. – Daijoubu Mar 25 '16 at 19:51
  • ... `canvas.tag_bind("sword","<1>",Buy_Sword)` prehaps? if you need to pass an argument to `Buy` then you can use `functools.partial` `from functools import partial ; ... canvas.tag_bind(word,"<1>",partial(Buy,word))` – Tadhg McDonald-Jensen Mar 25 '16 at 19:55
  • I've never used functools.partial. could you show me how this would work with what I have above. In a larger sense. What I mean is. I have a def buy(event) but i dont know how to make it trigger off of one word. I'm sorry I'm kind of a novice. – Daijoubu Mar 25 '16 at 19:58
  • that's ok everyone starts a novice, where you have `text=word` you can add right after it `tags=word` so that any [method on the Canvas Widget](http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/canvas-methods.html) that takes a tag or id can be given the word it is associated to. Then look at [any of the answers here](http://stackoverflow.com/questions/6920302/how-to-pass-arguments-to-a-button-command-in-tkinter) for passing in the extra arguments. I really don't want to post an answer because this is a duplicate. Good luck! – Tadhg McDonald-Jensen Mar 25 '16 at 20:35

2 Answers2

1

Here's what my solution was:

StoreItems = random.sample(set(['sword','pickaxe','toothpick','hammer','torch','saw']), 5)
#Selects 5 Random strings from the list. ^

XBASE, YBASE, DISTANCE = 300, 340, 50
for i, word in enumerate(StoreItems):  
    canvas.create_text(
        (XBASE, YBASE + i * DISTANCE),
        text=word, activefill="Medium Turquoise", anchor=W, fill="White", font=('Anarchistic',40), tags=word)

canvas.tag_bind('sword', '<ButtonPress-1>', BuySword)
canvas.tag_bind('pickaxe', '<ButtonPress-1>', BuyPick)
canvas.tag_bind('toothpick', '<ButtonPress-1>', BuyTooth)
canvas.tag_bind('hammer', '<ButtonPress-1>', BuyHammer)
canvas.tag_bind('torch', '<ButtonPress-1>', BuyTorch)
canvas.tag_bind('saw', '<ButtonPress-1>', BuySaw)

by setting the (tags=word) and making the tag.bind the same as the corresponding words it would assign that tag to only that word.

Daijoubu
  • 65
  • 1
  • 6
0

lets say your callback had an item argument as well as the event

def Buy(event,item):
    canvas.itemconfigure(item,fill="red")

then you can loop over the items in your store creating a unique callback wrapper for each like this:

for item in StoreItems:
    def Buy_Wrapper(event, item = item):
        Buy(event, item)
    canvas.tag_bind(item,"<Button-1>",Buy_Wrapper)

or the same thing inline with lambda expressions but I personally find them hard to read

for item in StoreItems:
    canvas.tag_bind(item,"<Button-1>",lambda event,item=item:Buy(event,item))

or with functools.partial specifying the keyword argument:

from functools import partial
for item in StoreItems:
    canvas.tag_bind(item,"<Button-1>",partial(Buy,item=item))
Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59