I have a GUI made with TKinter in Python. I would like to be able to display a message when my mouse cursor goes, for example, on top of a label or button. The purpose of th
The best way I have found to create a popup help window is to use the tix.Balloon
. I have modified it below to make it look better and show an example (note the use of tix.Tk
):
import tkinter as tk
import tkinter.tix as tix
class Balloon(tix.Balloon):
# A modified tix popup balloon (to change the default delay, bg and wraplength)
init_after = 1250 # Milliseconds
wraplength = 300 # Pixels
def __init__(self, master):
bg = root.cget("bg")
# Call the parent
super().__init__(master, initwait=self.init_after)
# Change background colour
for i in self.subwidgets_all():
i.config(bg=bg)
# Modify the balloon label
self.message.config(wraplength=self.wraplength)
root = tix.Tk()
l = tk.Label(root, text="\n".join(["text"] * 5))
l.pack()
b = Balloon(root.winfo_toplevel())
b.bind_widget(l, balloonmsg="Some random text")
root.mainloop()
OLD ANSWER:
Here is an example using
and
as @bryanoakley suggested with a toplevel (with overridedirect
set to true). Use the hover_timer
class for easy use of this. This needs the widget and help-text (with an optional delay argument - default 0.5s) and can be easily called just by initiating the class and then cancelling it.
import threading, time
from tkinter import *
class hover_window (Toplevel):
def __init__ (self, coords, text):
super ().__init__ ()
self.geometry ("+%d+%d" % (coords [0], coords [1]))
self.config (bg = "white")
Label (self, text = text, bg = "white", relief = "ridge", borderwidth = 3, wraplength = 400, justify = "left").grid ()
self.overrideredirect (True)
self.update ()
self.bind ("", lambda event: self.destroy ())
class hover_timer:
def __init__ (self, widget, text, delay = 2):
self.wind, self.cancel_var, self.widget, self.text, self.active, self.delay = None, False, widget, text, False, delay
threading.Thread (target = self.start_timer).start ()
def start_timer (self):
self.active = True
time.sleep (self.delay)
if not self.cancel_var: self.wind = hover_window ((self.widget.winfo_rootx (), self.widget.winfo_rooty () + self.widget.winfo_height () + 20), self.text)
self.active = False
def delayed_stop (self):
while self.active: time.sleep (0.05)
if self.wind:
self.wind.destroy ()
self.wind = None
def cancel (self):
self.cancel_var = True
if not self.wind: threading.Thread (target = self.delayed_stop).start ()
else:
self.wind.destroy ()
self.wind = None
def start_help (event):
# Create a new help timer
global h
h = hover_timer (l, "This is some additional information.", 0.5)
def end_help (event):
# If therre is one, end the help timer
if h: h.cancel ()
if __name__ == "__main__":
# Create the tkinter window
root = Tk ()
root.title ("Hover example")
# Help class not created yet
h = None
# Padding round label
Frame (root, width = 50).grid (row = 1, column = 0)
Frame (root, height = 50).grid (row = 0, column = 1)
Frame (root, width = 50).grid (row = 1, column = 2)
Frame (root, height = 50).grid (row = 2, column = 1)
# Setup the label
l = Label (root, text = "Hover over me for information.", font = ("sans", 32))
l.grid (row = 1, column = 1)
l.bind ("", start_help)
l.bind ("", end_help)
# Tkinter mainloop
root.mainloop ()