我已经定义了类状态,它由两个相互关联的画布项组成。将该类的实例添加到tkinter画布之后,我想通过鼠标左键来标识实例。为此,我使用了canvas find_overlapped方法。但是,当然,我只获得实例的画布项id,而不是对象id(在类状态的实例上调用方法时需要对象id)。我如何从画布项目id派生对象id?请看下面的例子:
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()
根据acw1668的注释,我解决了这个问题:我添加了一个字典作为类变量。在任何时候创建类的新实例时,字典得到一个新条目。每个条目都以Canvas Item ID为键。每个条目的值是实例的引用。因此,通过查看这个字典,我能够将Canvas Item id转换为引用,然后我可以为每个引用调用方法(为了保持简单,我的示例没有这样的方法)。抱歉我的解释可能不太准确,我是SW开发新手
更新代码:
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()