Reputation: 707
I have defined the class state, which consists out of two tkinter canvas items. After adding an instance of this class to a tkinter canvas, I want to identify the instance by the left mouse button. I have used the canvas find_overlapping-method for this. But of course I only get the canvas item id of the instance instead of the object id (which I need for calling methods on the instances of the class state). How can I derive the object id from the canvas item id? Please look into this example:
from tkinter import *
class state():
def __init__(self, canvas, x_position, y_position, *args, **kwargs):
self.oval = canvas.create_oval(x_position-20, y_position-20, x_position+20, y_position+20, fill='cyan')
self.text = canvas.create_text(x_position, y_position, text='S1')
x, y= 40, 40
def insert_state(canvas):
global x, y
global id
id = state(canvas, x, y)
x += 40
y += 40
def identify(event, canvas):
canvas_item_id = canvas.find_overlapping(event.x,event.y,event.x,event.y)
print("Found canvas item with id ", canvas_item_id)
root = Tk()
canvas = Canvas(root)
canvas.grid()
button1 = Button(root, text='add state')
button1.grid()
button1.bind('<Button-1>', lambda event, canvas=canvas : insert_state (canvas))
canvas.bind ('<Button-1>', lambda event, canvas=canvas : identify (event, canvas))
root.mainloop()
Upvotes: 0
Views: 2688
Reputation: 707
Following the comment of acw1668, I have solved the problem: I added a dictionary as a class variable. At any time when a new instance of the class is created, the dictionary gets a new entry. Each entry has as key the Canvas Item ID. The value of each entry is the reference of the instance. So by looking into this dictionary I am able to convert Canvas Item IDs into references and afterwards I can call methods for each reference (my example has no such methods in order to keep it simple). Sorry for perhaps being not so exact in my explanation, I am new to SW development.
Updated code:
from tkinter import *
class state():
state_dict = {} # NEW DICTIONARY
def __init__(self, canvas, x_position, y_position, *args, **kwargs):
self.oval = canvas.create_oval(x_position-20, y_position-20, x_position+20, y_position+20, fill='cyan')
self.text = canvas.create_text(x_position, y_position, text='S1')
state.state_dict[self.oval] = self # NEW ENTRY TO THE DICTIONARY
x, y= 40, 40
def insert_state(canvas):
global x, y
global id
id = state(canvas, x, y)
x += 40
y += 40
def identify(event, canvas):
canvas_item_id = canvas.find_overlapping(event.x,event.y,event.x,event.y)
print("Found canvas item with id ", canvas_item_id[0])
print("Found reference ", state.state_dict[canvas_item_id[0]]) # SOLVED
root = Tk()
canvas = Canvas(root)
canvas.grid()
button1 = Button(root, text='add state')
button1.grid()
button1.bind('<Button-1>', lambda event, canvas=canvas : insert_state (canvas))
canvas.bind ('<Button-1>', lambda event, canvas=canvas : identify (event, canvas))
root.mainloop()
Upvotes: 1