0

I have written a custom tkinter widget, TooltipLabel. When the cursor enters the label, it pops up a text widget that displays text. On windows, this works. But once I tested it on macos, the tooltip would not popup, even though the method to do so is getting called

I tried using this solution, but it didn't help.

Here's the PoC:

import math
import tkinter as tk
from tkinter import ttk

class Tooltip(object):
    """This widget adds a tooltip to a given widget, that displays when the cursor hovers over it"""
    def __init__(self, widget):
        self.widget = widget
        self.tooltip = None
        self.text = None
    #end init


    def show_tooltip(self, text):
        self.text = text
        if self.tooltip or not self.text:
            return

        x, y, cx, cy = self.widget.bbox("insert")
        x = x + self.widget.winfo_rootx() + 45
        y = y + cy + self.widget.winfo_rooty() + 30

        self.tooltip = tooltip_window = tk.Toplevel(self.widget)
        tooltip_window.wm_overrideredirect(1)   # removes the default window hide/maximize/close buttons
        tooltip_window.wm_geometry("+%d+%d" % (x, y))

        self._add_tooltip_text(tooltip_window)
    #end show_tooltip


    def hide_tooltip(self):
        tooltip_window = self.tooltip
        self.tooltip = None
        if tooltip_window:
            tooltip_window.destroy()
    #end hide_tooltip


    def _add_tooltip_text(self, tooltip_window):
        tooltip = tk.Text(tooltip_window, relief=tk.SOLID, width=40, wrap=tk.WORD)
        height = math.ceil(len(self.text) / 40) + self.text.count('\n')
        tooltip.insert(tk.END, self.text)
        tooltip.config(state=tk.DISABLED, height=height)
        tooltip.pack(ipadx=1)
    #end _add_tooltip_text
#end class Tooltip


def add_tooltip(widget, text):
    tooltip = Tooltip(widget)

    def enter(event):
        print(event)
        print(event.widget)
        print("Tooltip: %s" % text)
        tooltip.show_tooltip(text)
    #end enter

    def leave(event):
        tooltip.hide_tooltip()
    #end leave

    widget.bind('<Enter>', enter)
    widget.bind('<Leave>', leave)
#end add_tooltip

class TooltipLabel(ttk.Label):
    """This widget extends ttk.Label, and displays a tooltip when the cursor hovers over it"""
    def __init__(self, parent, tooltip_dict_key, **kwargs):
        ttk.Label.__init__(self, parent, **kwargs)

        self.parent = parent
        self.tooltip_text = None

        self.fetch_tooltip_text(tooltip_dict_key)
        add_tooltip(self, self.tooltip_text)
    #end init


    def fetch_tooltip_text(self, tooltip_dict_key):
        self.tooltip_text = "Testing tooltip"
    #end fetch_tooltip_text
#end class TooltipLabel



def main():
    root = tk.Tk()
    label = TooltipLabel(root, "tooltip_dict_key", text="testing")
    label.pack()

    root.mainloop()



if __name__ == "__main__":
    main()

I would expect the tooltip to pop up and display the text "Testing tooltip". This doesn't happen even though the event fires.

The output I get from the print statements:

<Enter event focus=False x=43 y=20>
.!tooltiplabel
Tooltip: Testing tooltip
wolfy
  • 113
  • 1
  • 7

1 Answers1

0

Try adding below after the line: tooltip_window.wm_geometry("+%d+%d" % (x, y))

tooltip_window.update_idletasks()
tooltip_window.lift()
Andyka
  • 36
  • 1