【问题标题】:python tkinter how to find the closest item that is in a specific list with canvaspython tkinter如何使用画布找到特定列表中最近的项目
【发布时间】:2021-03-30 14:55:42
【问题描述】:

我知道如何使用 canvas.find_closest() 方法在画布中找到最近的项目,但我希望它找到遵循特定条件的最接近的项目,就像它在列表中一样

例如:

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 之后找到最近的

【问题讨论】:

    标签: python tkinter canvas find


    【解决方案1】:

    我不知道有什么好的方法可以做到这一点。我可以通过制作一个自定义的 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() 非常有问题,非常规并且可能会破坏此代码。按照我展示的标准方式进行。

    【讨论】:

      猜你喜欢
      • 2010-09-11
      • 2012-09-30
      • 1970-01-01
      • 1970-01-01
      • 2022-12-23
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2016-11-21
      相关资源
      最近更新 更多