简体   繁体   English

Tkinter Canvas-如何在跨越多个对象的区域上创建事件(Python2)

[英]Tkinter Canvas - how to create event over an area spanning multiple objects (Python2)

I want to create a tkinter event that will treat multiple rectangles as one rectangle. 我想创建一个tkinter事件,它将多个矩形视为一个矩形。 Previously I gave all three rectangles the same tag and tied the event to the tag (enter and leave) but the problem is that it registered separate enter and leave calls each time I move the mouse from one rectangle to another, even though they are touching. 以前,我给所有三个矩形都添加了相同的标签,并将事件绑定到标签(输入和离开),但是问题是,每次我将鼠标从一个矩形移动到另一个矩形时,即使它们正在触摸,它也会分别注册回车和离开电话。

Because I pull up a popup on enter and destroy it on leave, constantly creating and destroying the same popup hurts the user experience (and the contents take about half a second to generate). 因为我在输入时弹出一个弹出窗口,然后在休假时将其破坏,所以不断创建和破坏相同的弹出窗口会损害用户体验(并且生成内容大约需要半秒钟)。

How do I create an event that will respond to multiple connected rectangles as if they are one object? 如何创建一个事件,该事件将响应多个相连的矩形,就像它们是一个对象一样?

Here is the code I've tried so far, without content not related to this question: 这是到目前为止我尝试过的代码,没有与这个问题无关的内容:

    import Tkinter as Tk

    class PopupBox:

        def __init__(self):
            self._master = Tk.Tk()

            self._popup = Tk.Toplevel()
            self._popup.destroy()

            self._canv = Tk.Canvas(self._master)
            self._canv.pack()

            self._canv.create_rectangle((50,50,100,100), fill='green', outline='', tags='test')
            self._canv.create_rectangle((50,100,100,150), fill='yellow', outline='', tags='test')
            self._canv.create_rectangle((50,150,100,200), fill='red', outline='', tags='test')

            self._canv.tag_bind('test', '<Enter>', self.enter)
            self._canv.tag_bind('test', '<Leave>', self.leave)

            self._master.mainloop()

        def enter(self, event):
            if self._popup.winfo_exists() == 1:
                self._popup.destroy()
            self._popup = Tk.Toplevel(self._master)
            self._popup.geometry('+%d+%d' % (event.x_root + 50, event.y_root + 50))

        def leave(self, event):
            if self._popup.winfo_exists():
                self._popup.destroy()

if __name__ == '__main__':

    x = PopupBox()

Here is a similar question that does not have the answer I need, since it ties the event to the entire canvas: 这是一个类似的问题,没有我需要的答案,因为它将事件与整个画布相关联:

how to create a transparent rectangle responding to click event in Tkinter 如何创建一个透明的矩形,以响应Tkinter中的click事件

I think a fairly simple solution would be to not destroy the popup immediately. 我认为一个相当简单的解决方案是不立即销毁弹出窗口。 Schedule it to be deleted about a short delay, say 200-500ms or so. 安排将其删除大约200-500ms左右的短暂延迟。 If you detect an <Enter> event to another rectangle with the same tag during that time span, cancel the destruction. 如果在该时间段内检测到另一个具有相同标签的矩形的<Enter>事件,请取消销毁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM