Display message when hovering over something with mouse cursor in Python

Learn display message when hovering over something with mouse cursor in python with practical examples, diagrams, and best practices. Covers python, tkinter, tooltip development techniques with vis...

Creating Interactive Tooltips in Python Tkinter Applications

Hero image for Display message when hovering over something with mouse cursor in Python

Learn how to implement dynamic tooltips that display messages when a user hovers their mouse cursor over widgets in Python's Tkinter GUI framework.

Adding tooltips to your graphical user interface (GUI) applications can significantly enhance user experience by providing contextual information without cluttering the main interface. In Python's Tkinter, creating a tooltip involves detecting mouse hover events and dynamically displaying a small, temporary window with your desired message. This article will guide you through the process of building a reusable tooltip mechanism for various Tkinter widgets.

Understanding the Core Concept

A tooltip's functionality relies on event binding. Specifically, we need to bind events for when the mouse enters a widget's area (<Enter>) and when it leaves (<Leave>). When the mouse enters, a small Toplevel window is created and positioned near the cursor, displaying the tooltip text. When the mouse leaves, this Toplevel window is destroyed. To prevent flickering or premature display, a short delay is often introduced before the tooltip appears.

sequenceDiagram
    participant User
    participant TkinterApp
    participant Widget
    participant Tooltip

    User->>Widget: Mouse enters widget area
    Widget->>TkinterApp: <Enter> event triggered
    TkinterApp->>Tooltip: Start delay timer
    alt Delay expires
        Tooltip->>TkinterApp: Create Toplevel window with text
        TkinterApp->>User: Display tooltip
    else User moves mouse out
        User->>Widget: Mouse leaves widget area
        Widget->>TkinterApp: <Leave> event triggered
        TkinterApp->>Tooltip: Cancel delay timer (if active)
        TkinterApp->>Tooltip: Destroy Toplevel window
        Tooltip->>User: Hide tooltip
    end

Sequence diagram illustrating the tooltip display and hide mechanism.

Implementing a Reusable Tooltip Class

To make tooltips easy to add to multiple widgets, we'll create a Tooltip class. This class will encapsulate the logic for creating, showing, and hiding the tooltip window, along with managing the delay. It will take the parent widget and the text to display as arguments.

import tkinter as tk

class Tooltip:
    def __init__(self, widget, text):
        self.widget = widget
        self.text = text
        self.tooltip_window = None
        self.id = None
        self.x = 0
        self.y = 0
        self.widget.bind("<Enter>", self.enter)
        self.widget.bind("<Leave>", self.leave)
        self.widget.bind("<ButtonPress>", self.leave)

    def enter(self, event=None):
        self.schedule()

    def leave(self, event=None):
        self.unschedule()
        self.hide()

    def schedule(self):
        self.unschedule()
        self.id = self.widget.after(500, self.show) # 500ms delay

    def unschedule(self):
        if self.id:
            self.widget.after_cancel(self.id)
            self.id = None

    def show(self):
        if self.tooltip_window or not self.text: # Don't show if already visible or no text
            return
        x, y, cx, cy = self.widget.bbox("insert")
        x += self.widget.winfo_rootx() + 25
        y += self.widget.winfo_rooty() + 20
        # Creates a toplevel window
        self.tooltip_window = tk.Toplevel(self.widget)
        # Leaves only the label and removes the app window
        self.tooltip_window.wm_overrideredirect(True)
        self.tooltip_window.wm_geometry(f"+{x}+{y}")

        label = tk.Label(self.tooltip_window,
                         text=self.text,
                         justify='left',
                         background="#ffffe0",
                         relief='solid',
                         borderwidth=1,
                         font=("tahoma", "8", "normal"))
        label.pack(ipadx=1)

    def hide(self):
        if self.tooltip_window:
            self.tooltip_window.destroy()
        self.tooltip_window = None

# Example Usage:
if __name__ == "__main__":
    root = tk.Tk()
    root.title("Tooltip Example")
    root.geometry("300x200")

    button1 = tk.Button(root, text="Hover over me!")
    button1.pack(pady=20)
    Tooltip(button1, "This is a helpful tooltip for Button 1.")

    label1 = tk.Label(root, text="Another widget with a tooltip")
    label1.pack(pady=10)
    Tooltip(label1, "You're hovering over a Label widget.")

    root.mainloop()

Python code for a reusable Tkinter Tooltip class and example usage.

Customizing Tooltip Appearance and Behavior

The provided Tooltip class offers a basic but functional tooltip. You can easily customize its appearance and behavior by modifying the show method:

  • Font and Colors: Adjust the font, background, foreground, relief, and borderwidth properties of the tk.Label widget within the show method.
  • Delay: Change the 500 (milliseconds) in self.widget.after(500, self.show) to increase or decrease the hover delay.
  • Positioning: The x and y coordinates are calculated to place the tooltip slightly offset from the widget. You can modify + 25 and + 20 to change this offset.
  • Dynamic Text: You could extend the class to accept a function that returns the tooltip text, allowing for dynamic messages based on application state.

1. Integrate the Tooltip Class

Copy the Tooltip class definition into your Python Tkinter application file.

2. Instantiate Tooltips for Widgets

For each widget you want to have a tooltip, create an instance of the Tooltip class, passing the widget object and the desired text: Tooltip(my_widget, "Your tooltip message here.").

3. Run Your Application

Execute your Tkinter application. Hover your mouse over the configured widgets to see the tooltips appear after a short delay.