Source code for frontend.ui_dialogs.tooltip

"""Tooltip binding for Tkinter widgets."""

from typing import Any, Optional
from tkinter import Toplevel, ttk

from config import UI_STYLE


[docs] def bind_tooltip(widget: Any, text: str, delay_ms: int = 500) -> None: """ Bind a tooltip to a Tkinter widget. Shows a tooltip window after a delay when the mouse enters the widget, and hides it when the mouse leaves. Uses a contrasting background and border so the tooltip is visible over the UI. Args: widget: Tkinter widget to bind the tooltip to. text: Tooltip text to display when mouse hovers over the widget. delay_ms: Delay in milliseconds before showing the tooltip (default: ``500``). """ tooltip_window: Optional[Toplevel] = None after_id: Optional[str] = None def show_tooltip() -> None: nonlocal tooltip_window if tooltip_window is not None: return tooltip_window = Toplevel(widget) tooltip_window.wm_overrideredirect(True) tooltip_window.wm_geometry("+0+0") tooltip_window.configure(background=UI_STYLE["tooltip_border"]) label = ttk.Label( tooltip_window, text=text, style="Tooltip.TLabel", ) label.pack(padx=1, pady=1) widget.update_idletasks() x = widget.winfo_rootx() + 20 y = widget.winfo_rooty() + widget.winfo_height() + 4 tooltip_window.wm_geometry(f"+{x}+{y}") def hide_tooltip() -> None: nonlocal tooltip_window, after_id if after_id is not None: widget.after_cancel(after_id) after_id = None if tooltip_window is not None: tooltip_window.destroy() tooltip_window = None def on_enter(_event: Any) -> None: nonlocal after_id after_id = widget.after(delay_ms, show_tooltip) def on_leave(_event: Any) -> None: hide_tooltip() widget.bind("<Enter>", on_enter) widget.bind("<Leave>", on_leave)