60 lines
1.7 KiB
Python
60 lines
1.7 KiB
Python
import tkinter as tk
|
|
|
|
|
|
class ToolTip:
|
|
"""Lightweight tooltip that appears after a delay when hovering a widget.
|
|
|
|
Usage:
|
|
ToolTip(widget, "help text", delay=1000)
|
|
"""
|
|
|
|
def __init__(self, widget, text, delay=1000):
|
|
self.widget = widget
|
|
self.text = text
|
|
self.delay = delay
|
|
self._id = None
|
|
self._tipwindow = None
|
|
widget.bind("<Enter>", self._on_enter, add=True)
|
|
widget.bind("<Leave>", self._on_leave, add=True)
|
|
widget.bind("<ButtonPress>", self._on_leave, add=True)
|
|
|
|
def _on_enter(self, _event=None):
|
|
self._schedule()
|
|
|
|
def _on_leave(self, _event=None):
|
|
self._unschedule()
|
|
self._hide()
|
|
|
|
def _schedule(self):
|
|
self._unschedule()
|
|
self._id = self.widget.after(self.delay, self._show)
|
|
|
|
def _unschedule(self):
|
|
if self._id:
|
|
try:
|
|
self.widget.after_cancel(self._id)
|
|
except Exception:
|
|
pass
|
|
self._id = None
|
|
|
|
def _show(self):
|
|
if self._tipwindow or not self.text:
|
|
return
|
|
x = self.widget.winfo_rootx() + 20
|
|
y = self.widget.winfo_rooty() + self.widget.winfo_height() + 5
|
|
tw = tk.Toplevel(self.widget)
|
|
tw.wm_overrideredirect(True)
|
|
tw.wm_geometry(f"+{x}+{y}")
|
|
lbl = tk.Label(tw, text=self.text, justify='left', background='#ffffe0', relief='solid', borderwidth=1,
|
|
font=(None, 9))
|
|
lbl.pack(ipadx=4, ipady=2)
|
|
self._tipwindow = tw
|
|
|
|
def _hide(self):
|
|
if self._tipwindow:
|
|
try:
|
|
self._tipwindow.destroy()
|
|
except Exception:
|
|
pass
|
|
self._tipwindow = None
|