簡體   English   中英

python tkinter 如何使用 canvas 查找特定列表中最接近的項目

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM