2

我正在开发一个需要重新定位画布项目的应用程序。我开发了以下 GrabbablePoint 类,但新点不是当前的,除非我将鼠标移开然后再移回该点。

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk

class grabbablePoint:

    def __init__(self, canvas, x, y, r):
        if not(canvas.find_withtag(tk.CURRENT)):
            h = canvas.create_oval(x-r, y-r, x+r, y+r)
            canvas.tag_bind(h, '<Enter>', lambda e,hh=h: canvas.itemconfig(hh,fill='#FF0000'))
            canvas.tag_bind(h, '<Leave>', lambda e,hh=h: canvas.itemconfig(hh,fill=''))
            canvas.tag_bind(h, '<B1-Motion>', lambda e,hh=h: canvas.coords(hh,e.x-r,e.y-r,e.x+r,e.y+r))

if __name__ == '__main__':
    canv = tk.Canvas(width=400, height=300, bg='#CCCCFF')
    canv.bind('<Button-1>',lambda e: grabbablePoint(canv,e.x,e.y,3))
    canv.pack()
    tk.mainloop()

结果,如果我在离开和返回之前单击一个点,它会在第一个点的顶部生成另一个点。奇怪的是,我可以通过向 create_oval 添加填充属性来纠正这种不良行为...

        h = canvas.create_oval(x-r, y-r, x+r, y+r, fill='#FF0000')

现在它完美地工作了。谁能向我解释这里发生了什么?为什么添加属性会触发 CURRENT 以及为什么不设置其他属性?

4

1 回答 1

1

如果您在没有填充的情况下绘制形状,从 Tkinter 的角度来看,您不是在悬停形状,而是在悬停背景。如果没有填充,只有形状的笔划对鼠标事件(进入、离开、当前......)是敏感的。

您可以使用find_家庭的另一种方法解决此问题:find_closest, find_overlapping.

请注意,由于鼠标事件采样,您也可以在不触发回车的情况下进入现有形状(跳过笔划),因此不会显示您的背景,这意味着您的圆圈不会移动,并且您将创建另一个圆圈(但不太可能使用您的半径和鼠标)。

于 2012-10-30T18:44:26.480 回答