如何找到哪个 Canvas 项目更接近 tkinter 中单击的点?

How to find which Canvas item is closer to the point clicked in tkinter?

我想找到哪个 Canvas 项目更接近我点击的点。我正在尝试使用 find the closest 但我无法有效地使用它。我正在尝试制作一个 itemlist,然后在 itemlist 中找到最接近的项目。我也有 self 关键字,因为我正在尝试使用 类

来完成所有这些
def initUI(self):
    self.canvas = Canvas(self.parent)
    self.item1 = self.canvas.create_oval(50, 50, 60, 60, fill="red")
    self.item2 = self.canvas.create_oval(100, 100, 110, 110, fill="red")
    self.item3 = self.canvas.create_oval(150, 150, 160, 160, fill="red")
    self.itemlist = []
    self.itemlist.append(self.item1)
    self.itemlist.append(self.item2)
    self.itemlist.append(self.item3)
    print(self.itemlist) 
    self.canvas.pack()
    self.canvas.bind("<Button-1>", self.find_closest)

def find_closest(self, event):
""" """

正如评论中所指出的,您可以使用 Canvas 方法 find_closest() 来完成所需的操作。下面是根据您问题中的代码执行此操作的可运行示例。它使用辅助字典将 canvas 对象的 ID 映射到任意字符串(在示例中称为“名称”)。

import tkinter as tk
from tkinter.constants import *

class MyClass:
    def __init__(self, parent):
        self.parent = parent
        self.initUI()

    def initUI(self):
        self.canvas = tk.Canvas(self.parent)
        self.canvas.pack()
        self.canvas.bind("<Button-1>", self.find_closest)

       # Create dictionary mapping canvas object ids to a name.
        self.object_names = {}
        id = self.canvas.create_oval(50, 50, 60, 60, fill="Red")
        self.object_names[id] = 'Red object'
        id = self.canvas.create_oval(100, 100, 110, 110, fill="Blue")
        self.object_names[id] = 'Blue object'
        id = self.canvas.create_oval(150, 150, 160, 160, fill="Green")
        self.object_names[id] = 'Green object'

        self.name_lbl1 = tk.Label(self.parent, text='Closest object:')
        self.name_lbl1.pack(side=LEFT)

        self.name_var = tk.StringVar(value='')
        self.name_lbl2 = tk.Label(self.parent, textvariable=self.name_var)
        self.name_lbl2.pack(side=LEFT)

    def find_closest(self, event):
        if (closest := self.canvas.find_closest(event.x, event.y)):
            obj_id = closest[0]
            self.name_var.set(self.object_names[obj_id])  # Updates lbl2.

if __name__ == '__main__':
    root = tk.Tk()
    instance = MyClass(root)
    root.mainloop()

截图运行: