0
votes

I want to create a tkinter event that will treat multiple rectangles as one rectangle. 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

1

1 Answers

0
votes

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. If you detect an <Enter> event to another rectangle with the same tag during that time span, cancel the destruction.