| 1 | # general purpose 'tooltip' routines - currently unused in idlefork
|
|---|
| 2 | # (although the 'calltips' extension is partly based on this code)
|
|---|
| 3 | # may be useful for some purposes in (or almost in ;) the current project scope
|
|---|
| 4 | # Ideas gleaned from PySol
|
|---|
| 5 |
|
|---|
| 6 | from Tkinter import *
|
|---|
| 7 |
|
|---|
| 8 | class ToolTipBase:
|
|---|
| 9 |
|
|---|
| 10 | def __init__(self, button):
|
|---|
| 11 | self.button = button
|
|---|
| 12 | self.tipwindow = None
|
|---|
| 13 | self.id = None
|
|---|
| 14 | self.x = self.y = 0
|
|---|
| 15 | self._id1 = self.button.bind("<Enter>", self.enter)
|
|---|
| 16 | self._id2 = self.button.bind("<Leave>", self.leave)
|
|---|
| 17 | self._id3 = self.button.bind("<ButtonPress>", self.leave)
|
|---|
| 18 |
|
|---|
| 19 | def enter(self, event=None):
|
|---|
| 20 | self.schedule()
|
|---|
| 21 |
|
|---|
| 22 | def leave(self, event=None):
|
|---|
| 23 | self.unschedule()
|
|---|
| 24 | self.hidetip()
|
|---|
| 25 |
|
|---|
| 26 | def schedule(self):
|
|---|
| 27 | self.unschedule()
|
|---|
| 28 | self.id = self.button.after(1500, self.showtip)
|
|---|
| 29 |
|
|---|
| 30 | def unschedule(self):
|
|---|
| 31 | id = self.id
|
|---|
| 32 | self.id = None
|
|---|
| 33 | if id:
|
|---|
| 34 | self.button.after_cancel(id)
|
|---|
| 35 |
|
|---|
| 36 | def showtip(self):
|
|---|
| 37 | if self.tipwindow:
|
|---|
| 38 | return
|
|---|
| 39 | # The tip window must be completely outside the button;
|
|---|
| 40 | # otherwise when the mouse enters the tip window we get
|
|---|
| 41 | # a leave event and it disappears, and then we get an enter
|
|---|
| 42 | # event and it reappears, and so on forever :-(
|
|---|
| 43 | x = self.button.winfo_rootx() + 20
|
|---|
| 44 | y = self.button.winfo_rooty() + self.button.winfo_height() + 1
|
|---|
| 45 | self.tipwindow = tw = Toplevel(self.button)
|
|---|
| 46 | tw.wm_overrideredirect(1)
|
|---|
| 47 | tw.wm_geometry("+%d+%d" % (x, y))
|
|---|
| 48 | self.showcontents()
|
|---|
| 49 |
|
|---|
| 50 | def showcontents(self, text="Your text here"):
|
|---|
| 51 | # Override this in derived class
|
|---|
| 52 | label = Label(self.tipwindow, text=text, justify=LEFT,
|
|---|
| 53 | background="#ffffe0", relief=SOLID, borderwidth=1)
|
|---|
| 54 | label.pack()
|
|---|
| 55 |
|
|---|
| 56 | def hidetip(self):
|
|---|
| 57 | tw = self.tipwindow
|
|---|
| 58 | self.tipwindow = None
|
|---|
| 59 | if tw:
|
|---|
| 60 | tw.destroy()
|
|---|
| 61 |
|
|---|
| 62 | class ToolTip(ToolTipBase):
|
|---|
| 63 | def __init__(self, button, text):
|
|---|
| 64 | ToolTipBase.__init__(self, button)
|
|---|
| 65 | self.text = text
|
|---|
| 66 | def showcontents(self):
|
|---|
| 67 | ToolTipBase.showcontents(self, self.text)
|
|---|
| 68 |
|
|---|
| 69 | class ListboxToolTip(ToolTipBase):
|
|---|
| 70 | def __init__(self, button, items):
|
|---|
| 71 | ToolTipBase.__init__(self, button)
|
|---|
| 72 | self.items = items
|
|---|
| 73 | def showcontents(self):
|
|---|
| 74 | listbox = Listbox(self.tipwindow, background="#ffffe0")
|
|---|
| 75 | listbox.pack()
|
|---|
| 76 | for item in self.items:
|
|---|
| 77 | listbox.insert(END, item)
|
|---|
| 78 |
|
|---|
| 79 | def main():
|
|---|
| 80 | # Test code
|
|---|
| 81 | root = Tk()
|
|---|
| 82 | b = Button(root, text="Hello", command=root.destroy)
|
|---|
| 83 | b.pack()
|
|---|
| 84 | root.update()
|
|---|
| 85 | tip = ListboxToolTip(b, ["Hello", "world"])
|
|---|
| 86 | root.mainloop()
|
|---|
| 87 |
|
|---|
| 88 | if __name__ == '__main__':
|
|---|
| 89 | main()
|
|---|