![](/img/trans.png)
[英]How to find is a canvas item is touching another canvas item, Tkinter
[英]python tkinter how to find the closest item that is in a specific list with canvas
我知道如何使用 canvas.find_closest() 方法在 canvas 中找到最接近的項目,但我希望它找到遵循特定條件的最接近的項目,就像它在列表中一樣
例如:
from tkinter import *
tk=Tk()
canvas=Canvas(tk, width=1000, height=100)
item1=canvas.create_rectangle(0, 0, 50, 50)
item2=canvas.create_rectangle(30, 30, 80, 80)
item3=canvas.create_rectangle(200, 200, 300, 300)
list_of_items=[item1, item2]
def find_closest_item(event):
item=canvas.find_closest(event.x, event.y)
canvas.bind("<Button-1>", find_closest_item)
在這段代碼中,我希望如果我點擊 item3 它不會找到它,因為它不在“list_of_items”中,並且它會在 item3 之后找到最接近的
我不知道有什么好方法可以做到這一點。 我可以通過制作一個自定義 Canvas 小部件來破解解決方案,該小部件保留一個單獨的區域來查找東西,這樣我就可以定義一個finditem
參數。
import tkinter as tk
from types import MethodType
class FindCanvas(tk.Canvas):
"""
A type of Canvas where items can be exempted from find methods
including find, find_above, find_all, find_below, find_closest,
find_enclosed, find_overlapping, find_withtag
"""
def __init__(self, master=None, **kwargs):
super().__init__(master, **kwargs)
self.finder = tk.Canvas(master, **kwargs)
# these methods need to be called in both instances
for methodname in ("move", "delete", "coords", "dchars"):
def func(self, *args, methodname=methodname, **kwargs):
getattr(self.finder, methodname)(*args, **kwargs)
return getattr(super(), methodname)(*args, **kwargs)
setattr(self, methodname, MethodType(func, self))
def find(self, *args, **kwargs):
return self.finder.find(*args, **kwargs)
def _create(self, itemType, args, kw):
kwargs = kw
if not kw.pop("finditem", True):
kwargs = dict(list(kw.items()) + [('state', 'hidden')]) # yes, I know about 3.9
self.finder._create(itemType, args, kwargs)
return super()._create(itemType, args, kw)
### DEMO use:
def find_closest_item(event):
item=canvas.find_closest(event.x, event.y)
lbl.config(text="Closest item is item number "+str(item))
root=tk.Tk()
canvas=FindCanvas(root, width=400, height=400)
canvas.pack()
item1=canvas.create_rectangle(0, 0, 50, 50)
item2=canvas.create_rectangle(30, 30, 80, 80)
item3=canvas.create_rectangle(200, 200, 300, 300, finditem=False)
item4=canvas.create_oval(30, 300, 100, 400, finditem=False)
item5=canvas.create_rectangle(60, 340, 80, 380)
canvas.bind("<Button-1>", find_closest_item)
lbl = tk.Label(root)
lbl.pack()
tk.mainloop()
順便說一句,使用from tkinter import *
和tk=Tk()
非常有問題,非常規並且可能會破壞此代碼。 按照我展示的標准方式進行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.