How do I display tooltips in Tkinter?
Tooltips are those little bits of text that popup when the开发者_运维知识库 mouse hovers over a widget for a certain duration of time.
How can I add a tooltip message to my tkinter
Python application?
I tried the code in the blog post mentioned by ars, and also tried the code from the IDLE lib.
While both worked, I didn't like how the tooltip from IDLE was limited in size (had to manually enter new lines as separate lists) , and how the tips appeared immediately in the code form the blog post.
So I made a hybrid between the two. It lets you specify a wrap length and hover time, with no restriction on each:
""" tk_ToolTip_class101.py
gives a Tkinter widget a tooltip as the mouse is above the widget
tested with Python27 and Python34 by vegaseat 09sep2014
www.daniweb.com/programming/software-development/code/484591/a-tooltip-class-for-tkinter
Modified to include a delay time by Victor Zaccardo, 25mar16
"""
try:
# for Python2
import Tkinter as tk
except ImportError:
# for Python3
import tkinter as tk
class CreateToolTip(object):
"""
create a tooltip for a given widget
"""
def __init__(self, widget, text='widget info'):
self.waittime = 500 #miliseconds
self.wraplength = 180 #pixels
self.widget = widget
self.text = text
self.widget.bind("<Enter>", self.enter)
self.widget.bind("<Leave>", self.leave)
self.widget.bind("<ButtonPress>", self.leave)
self.id = None
self.tw = None
def enter(self, event=None):
self.schedule()
def leave(self, event=None):
self.unschedule()
self.hidetip()
def schedule(self):
self.unschedule()
self.id = self.widget.after(self.waittime, self.showtip)
def unschedule(self):
id = self.id
self.id = None
if id:
self.widget.after_cancel(id)
def showtip(self, event=None):
x = y = 0
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.tw = tk.Toplevel(self.widget)
# Leaves only the label and removes the app window
self.tw.wm_overrideredirect(True)
self.tw.wm_geometry("+%d+%d" % (x, y))
label = tk.Label(self.tw, text=self.text, justify='left',
background="#ffffff", relief='solid', borderwidth=1,
wraplength = self.wraplength)
label.pack(ipadx=1)
def hidetip(self):
tw = self.tw
self.tw= None
if tw:
tw.destroy()
# testing ...
if __name__ == '__main__':
root = tk.Tk()
btn1 = tk.Button(root, text="button 1")
btn1.pack(padx=10, pady=5)
button1_ttp = CreateToolTip(btn1, \
'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, '
'consectetur, adipisci velit. Neque porro quisquam est qui dolorem ipsum '
'quia dolor sit amet, consectetur, adipisci velit. Neque porro quisquam '
'est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.')
btn2 = tk.Button(root, text="button 2")
btn2.pack(padx=10, pady=5)
button2_ttp = CreateToolTip(btn2, \
"First thing's first, I'm the realest. Drop this and let the whole world "
"feel it. And I'm still in the Murda Bizness. I could hold you down, like "
"I'm givin' lessons in physics. You should want a bad Vic like this.")
root.mainloop()
Screenshot:
A simple solution in Python 3.7+
import tkinter as tk
from idlelib.tooltip import Hovertip
app = tk.Tk()
myBtn = tk.Button(app,text='?')
myBtn.pack(pady=30)
myTip = Hovertip(myBtn,'This is \na multiline tooltip.')
app.mainloop()
The Pmw.Balloon class from the Pmw toolkit for Tkinter will draw tool tips.
Also take a look at this blog post, which adapts some code from IDLE used for displaying tool tips with Tkinter.
First of all, I really like Alberto Vassena's tool tip and I tried to comment on his post with this bug correction, but as a new user I do not have enough points to make a comment, so I am making an answer. I hope this is acceptable.
There was a very small bug in Alberto Vassena's excellent answer and improved ToolTip.
Bug: For the actual label his code calls ttk.Label instead of tk.Label This resulted in the tooltip box being rendered but not the actual text until a further UI event such as another mouse move or a keyboard event.
Here is the corrected code for a full copy & paste:
import tkinter as tk
import tkinter.ttk as ttk
class Tooltip:
'''
It creates a tooltip for a given widget as the mouse goes on it.
see:
http://stackoverflow.com/questions/3221956/
what-is-the-simplest-way-to-make-tooltips-
in-tkinter/36221216#36221216
http://www.daniweb.com/programming/software-development/
code/484591/a-tooltip-class-for-tkinter
- Originally written by vegaseat on 2014.09.09.
- Modified to include a delay time by Victor Zaccardo on 2016.03.25.
- Modified
- to correct extreme right and extreme bottom behavior,
- to stay inside the screen whenever the tooltip might go out on
the top but still the screen is higher than the tooltip,
- to use the more flexible mouse positioning,
- to add customizable background color, padding, waittime and
wraplength on creation
by Alberto Vassena on 2016.11.05.
Tested on Ubuntu 16.04/16.10, running Python 3.5.2
TODO: themes styles support
'''
def __init__(self, widget,
*,
bg='#FFFFEA',
pad=(5, 3, 5, 3),
text='widget info',
waittime=400,
wraplength=250):
self.waittime = waittime # in miliseconds, originally 500
self.wraplength = wraplength # in pixels, originally 180
self.widget = widget
self.text = text
self.widget.bind("<Enter>", self.onEnter)
self.widget.bind("<Leave>", self.onLeave)
self.widget.bind("<ButtonPress>", self.onLeave)
self.bg = bg
self.pad = pad
self.id = None
self.tw = None
def onEnter(self, event=None):
self.schedule()
def onLeave(self, event=None):
self.unschedule()
self.hide()
def schedule(self):
self.unschedule()
self.id = self.widget.after(self.waittime, self.show)
def unschedule(self):
id_ = self.id
self.id = None
if id_:
self.widget.after_cancel(id_)
def show(self):
def tip_pos_calculator(widget, label,
*,
tip_delta=(10, 5), pad=(5, 3, 5, 3)):
w = widget
s_width, s_height = w.winfo_screenwidth(), w.winfo_screenheight()
width, height = (pad[0] + label.winfo_reqwidth() + pad[2],
pad[1] + label.winfo_reqheight() + pad[3])
mouse_x, mouse_y = w.winfo_pointerxy()
x1, y1 = mouse_x + tip_delta[0], mouse_y + tip_delta[1]
x2, y2 = x1 + width, y1 + height
x_delta = x2 - s_width
if x_delta < 0:
x_delta = 0
y_delta = y2 - s_height
if y_delta < 0:
y_delta = 0
offscreen = (x_delta, y_delta) != (0, 0)
if offscreen:
if x_delta:
x1 = mouse_x - tip_delta[0] - width
if y_delta:
y1 = mouse_y - tip_delta[1] - height
offscreen_again = y1 < 0 # out on the top
if offscreen_again:
# No further checks will be done.
# TIP:
# A further mod might automagically augment the
# wraplength when the tooltip is too high to be
# kept inside the screen.
y1 = 0
return x1, y1
bg = self.bg
pad = self.pad
widget = self.widget
# creates a toplevel window
self.tw = tk.Toplevel(widget)
# Leaves only the label and removes the app window
self.tw.wm_overrideredirect(True)
win = tk.Frame(self.tw,
background=bg,
borderwidth=0)
label = tk.Label(win,
text=self.text,
justify=tk.LEFT,
background=bg,
relief=tk.SOLID,
borderwidth=0,
wraplength=self.wraplength)
label.grid(padx=(pad[0], pad[2]),
pady=(pad[1], pad[3]),
sticky=tk.NSEW)
win.grid()
x, y = tip_pos_calculator(widget, label)
self.tw.wm_geometry("+%d+%d" % (x, y))
def hide(self):
tw = self.tw
if tw:
tw.destroy()
self.tw = None
if __name__ == '__main__':
import random
def further_text():
# texts generated at http://lorem-ipsum.perbang.dk/
short_text = ('Lorem ipsum dolor sit amet, mauris tellus, '
'porttitor torquent eu. Magna aliquet lorem, '
'cursus sit ac, in in. Dolor aliquet, cum integer. '
'Proin aliquet, porttitor pulvinar mauris. Tellus '
'lectus, amet cras, neque lacus quis. Malesuada '
'nibh. Eleifend nam, in eget a. Nec turpis, erat '
'wisi semper')
medium_text = ('Lorem ipsum dolor sit amet, suspendisse aenean '
'ipsum sollicitudin, pellentesque nunc ultrices ac '
'ut, arcu elit turpis senectus convallis. Ac orci '
'pretium sed gravida, tortor nulla felis '
'consectetuer, mauris egestas est erat. Ut enim '
'tellus at diam, ac sagittis vel proin. Massa '
'eleifend orci tortor sociis, scelerisque in pede '
'metus phasellus, est tempor gravida nam, ante '
'fusce sem tempor. Mi diam auctor vel pede, mus '
'non mi luctus luctus, lectus sit varius repellat '
'eu')
long_text = ('Lorem ipsum dolor sit amet, velit eu nam cursus '
'quisque gravida sollicitudin, felis arcu interdum '
'error quam quis massa, et velit libero ligula est '
'donec. Suspendisse fringilla urna ridiculus dui '
'volutpat justo, quisque nisl eget sed blandit '
'egestas, libero nullam magna sem dui nam, auctor '
'vehicula nunc arcu vel sed dictum, tincidunt vitae '
'id tristique aptent platea. Lacus eros nec proin '
'morbi sollicitudin integer, montes suspendisse '
'augue lorem iaculis sed, viverra sed interdum eget '
'ut at pulvinar, turpis vivamus ac pharetra nulla '
'maecenas ut. Consequat dui condimentum lectus nulla '
'vitae, nam consequat fusce ac facilisis eget orci, '
'cras enim donec aenean sed dolor aliquam, elit '
'lorem in a nec fringilla, malesuada curabitur diam '
'nonummy nisl nibh ipsum. In odio nunc nec porttitor '
'ipsum, nunc ridiculus platea wisi turpis praesent '
'vestibulum, suspendisse hendrerit amet quis vivamus '
'adipiscing elit, ut dolor nec nonummy mauris nec '
'libero, ad rutrum id tristique facilisis sed '
'ultrices. Convallis velit posuere mauris lectus sit '
'turpis, lobortis volutpat et placerat leo '
'malesuada, vulputate id maecenas at a volutpat '
'vulputate, est augue nec proin ipsum pellentesque '
'fringilla. Mattis feugiat metus ultricies repellat '
'dictum, suspendisse erat rhoncus ultricies in ipsum, '
'nulla ante pellentesque blandit ligula sagittis '
'ultricies, sed tortor sodales pede et duis platea')
text = random.choice([short_text, medium_text, long_text, long_text])
return '\nFurther info: ' + text
def main_01(wraplength=200):
# alias
stuff = further_text
root = tk.Tk()
frame = ttk.Frame(root)
btn_ne = ttk.Button(frame, text='North East')
btn_se = ttk.Button(frame, text='South East')
btn_sw = ttk.Button(frame, text='South West')
btn_nw = ttk.Button(frame, text='North West')
btn_center = ttk.Button(frame, text='Center')
btn_n = ttk.Button(frame, text='North')
btn_e = ttk.Button(frame, text='East')
btn_s = ttk.Button(frame, text='South')
btn_w = ttk.Button(frame, text='West')
Tooltip(btn_nw, text='North West' + stuff(), wraplength=wraplength)
Tooltip(btn_ne, text='North East' + stuff(), wraplength=wraplength)
Tooltip(btn_se, text='South East' + stuff(), wraplength=wraplength)
Tooltip(btn_sw, text='South West' + stuff(), wraplength=wraplength)
Tooltip(btn_center, text='Center' + stuff(), wraplength=wraplength)
Tooltip(btn_n, text='North' + stuff(), wraplength=wraplength)
Tooltip(btn_e, text='East' + stuff(), wraplength=wraplength)
Tooltip(btn_s, text='South' + stuff(), wraplength=wraplength)
Tooltip(btn_w, text='West' + stuff(), wraplength=wraplength)
r = 0
c = 0
pad = 10
btn_nw.grid(row=r, column=c, padx=pad, pady=pad, sticky=tk.NW)
btn_n.grid(row=r, column=c + 1, padx=pad, pady=pad, sticky=tk.N)
btn_ne.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.NE)
r += 1
btn_w.grid(row=r, column=c + 0, padx=pad, pady=pad, sticky=tk.W)
btn_center.grid(row=r, column=c + 1, padx=pad, pady=pad,
sticky=tk.NSEW)
btn_e.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.E)
r += 1
btn_sw.grid(row=r, column=c, padx=pad, pady=pad, sticky=tk.SW)
btn_s.grid(row=r, column=c + 1, padx=pad, pady=pad, sticky=tk.S)
btn_se.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.SE)
frame.grid(sticky=tk.NSEW)
for i in (0, 2):
frame.rowconfigure(i, weight=1)
frame.columnconfigure(i, weight=1)
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
root.title('Tooltip wraplength = {}'.format(wraplength))
root.mainloop()
def main():
print('Trying out three different wraplengths:')
for i, wl in enumerate((200, 250, 400), 1):
print(' ', i)
main_01(wl)
print('Done.')
main()
I would not recommend to use Tix
widgets, since Tix
is basically not supported anymore and usually causes a lot of problems.
The following is an example of a tooltip directly taken from the Python's idlelib
module:
# general purpose 'tooltip' routines - currently unused in idlefork
# (although the 'calltips' extension is partly based on this code)
# may be useful for some purposes in (or almost in ;) the current project scope
# Ideas gleaned from PySol
from tkinter import *
class ToolTipBase:
def __init__(self, button):
self.button = button
self.tipwindow = None
self.id = None
self.x = self.y = 0
self._id1 = self.button.bind("<Enter>", self.enter)
self._id2 = self.button.bind("<Leave>", self.leave)
self._id3 = self.button.bind("<ButtonPress>", self.leave)
def enter(self, event=None):
self.schedule()
def leave(self, event=None):
self.unschedule()
self.hidetip()
def schedule(self):
self.unschedule()
self.id = self.button.after(1500, self.showtip)
def unschedule(self):
id = self.id
self.id = None
if id:
self.button.after_cancel(id)
def showtip(self):
if self.tipwindow:
return
# The tip window must be completely outside the button;
# otherwise when the mouse enters the tip window we get
# a leave event and it disappears, and then we get an enter
# event and it reappears, and so on forever :-(
x = self.button.winfo_rootx() + 20
y = self.button.winfo_rooty() + self.button.winfo_height() + 1
self.tipwindow = tw = Toplevel(self.button)
tw.wm_overrideredirect(1)
tw.wm_geometry("+%d+%d" % (x, y))
self.showcontents()
def showcontents(self, text="Your text here"):
# Override this in derived class
label = Label(self.tipwindow, text=text, justify=LEFT,
background="#ffffe0", relief=SOLID, borderwidth=1)
label.pack()
def hidetip(self):
tw = self.tipwindow
self.tipwindow = None
if tw:
tw.destroy()
class ToolTip(ToolTipBase):
def __init__(self, button, text):
ToolTipBase.__init__(self, button)
self.text = text
def showcontents(self):
ToolTipBase.showcontents(self, self.text)
class ListboxToolTip(ToolTipBase):
def __init__(self, button, items):
ToolTipBase.__init__(self, button)
self.items = items
def showcontents(self):
listbox = Listbox(self.tipwindow, background="#ffffe0")
listbox.pack()
for item in self.items:
listbox.insert(END, item)
You could also import the module directly and use it:
from idlelib.ToolTip import *
def main():
root = Tk()
b = Button(root, text="Hello", command=root.destroy)
b.pack()
root.update()
tip = ListboxToolTip(b, ["Hello", "world"])
root.mainloop()
if __name__ == '__main__':
main()
I am using Python 3.4, and it is possible that other Python's distributions do not contain this ToolTip
module.
Since you're using Windows 7, your Python installation most probably already includes Tix. Use the Tix.Balloon widget. Sample code exists in the Python source tree.
Basically, you create a Tix.Balloon
widget, you bind it to other widgets through its .bind_widget
method and provide the balloon message using its balloonmsg
argument.
I have modified the Tooltip class crxguy52 has suggested. The class that follows should now work in almost any case, wherever you need to instantiate it: NW, N, NE, E, SE, S, SW, W.
The only case my class does not currently manage is the one in which the tooltip is simply taller than the entire screen (probably very rare, but by simply widening it by manually passing a larger wraplength can immediately solve that case as well).
import tkinter as tk
import tkinter.ttk as ttk
class Tooltip:
'''
It creates a tooltip for a given widget as the mouse goes on it.
see:
https://stackoverflow.com/questions/3221956/
what-is-the-simplest-way-to-make-tooltips-
in-tkinter/36221216#36221216
http://www.daniweb.com/programming/software-development/
code/484591/a-tooltip-class-for-tkinter
- Originally written by vegaseat on 2014.09.09.
- Modified to include a delay time by Victor Zaccardo on 2016.03.25.
- Modified
- to correct extreme right and extreme bottom behavior,
- to stay inside the screen whenever the tooltip might go out on
the top but still the screen is higher than the tooltip,
- to use the more flexible mouse positioning,
- to add customizable background color, padding, waittime and
wraplength on creation
by Alberto Vassena on 2016.11.05.
Tested on Ubuntu 16.04/16.10, running Python 3.5.2
TODO: themes styles support
'''
def __init__(self, widget,
*,
bg='#FFFFEA',
pad=(5, 3, 5, 3),
text='widget info',
waittime=400,
wraplength=250):
self.waittime = waittime # in miliseconds, originally 500
self.wraplength = wraplength # in pixels, originally 180
self.widget = widget
self.text = text
self.widget.bind("<Enter>", self.onEnter)
self.widget.bind("<Leave>", self.onLeave)
self.widget.bind("<ButtonPress>", self.onLeave)
self.bg = bg
self.pad = pad
self.id = None
self.tw = None
def onEnter(self, event=None):
self.schedule()
def onLeave(self, event=None):
self.unschedule()
self.hide()
def schedule(self):
self.unschedule()
self.id = self.widget.after(self.waittime, self.show)
def unschedule(self):
id_ = self.id
self.id = None
if id_:
self.widget.after_cancel(id_)
def show(self):
def tip_pos_calculator(widget, label,
*,
tip_delta=(10, 5), pad=(5, 3, 5, 3)):
w = widget
s_width, s_height = w.winfo_screenwidth(), w.winfo_screenheight()
width, height = (pad[0] + label.winfo_reqwidth() + pad[2],
pad[1] + label.winfo_reqheight() + pad[3])
mouse_x, mouse_y = w.winfo_pointerxy()
x1, y1 = mouse_x + tip_delta[0], mouse_y + tip_delta[1]
x2, y2 = x1 + width, y1 + height
x_delta = x2 - s_width
if x_delta < 0:
x_delta = 0
y_delta = y2 - s_height
if y_delta < 0:
y_delta = 0
offscreen = (x_delta, y_delta) != (0, 0)
if offscreen:
if x_delta:
x1 = mouse_x - tip_delta[0] - width
if y_delta:
y1 = mouse_y - tip_delta[1] - height
offscreen_again = y1 < 0 # out on the top
if offscreen_again:
# No further checks will be done.
# TIP:
# A further mod might automagically augment the
# wraplength when the tooltip is too high to be
# kept inside the screen.
y1 = 0
return x1, y1
bg = self.bg
pad = self.pad
widget = self.widget
# creates a toplevel window
self.tw = tk.Toplevel(widget)
# Leaves only the label and removes the app window
self.tw.wm_overrideredirect(True)
win = tk.Frame(self.tw,
background=bg,
borderwidth=0)
label = ttk.Label(win,
text=self.text,
justify=tk.LEFT,
background=bg,
relief=tk.SOLID,
borderwidth=0,
wraplength=self.wraplength)
label.grid(padx=(pad[0], pad[2]),
pady=(pad[1], pad[3]),
sticky=tk.NSEW)
win.grid()
x, y = tip_pos_calculator(widget, label)
self.tw.wm_geometry("+%d+%d" % (x, y))
def hide(self):
tw = self.tw
if tw:
tw.destroy()
self.tw = None
if __name__ == '__main__':
import random
def further_text():
# texts generated at http://lorem-ipsum.perbang.dk/
short_text = ('Lorem ipsum dolor sit amet, mauris tellus, '
'porttitor torquent eu. Magna aliquet lorem, '
'cursus sit ac, in in. Dolor aliquet, cum integer. '
'Proin aliquet, porttitor pulvinar mauris. Tellus '
'lectus, amet cras, neque lacus quis. Malesuada '
'nibh. Eleifend nam, in eget a. Nec turpis, erat '
'wisi semper')
medium_text = ('Lorem ipsum dolor sit amet, suspendisse aenean '
'ipsum sollicitudin, pellentesque nunc ultrices ac '
'ut, arcu elit turpis senectus convallis. Ac orci '
'pretium sed gravida, tortor nulla felis '
'consectetuer, mauris egestas est erat. Ut enim '
'tellus at diam, ac sagittis vel proin. Massa '
'eleifend orci tortor sociis, scelerisque in pede '
'metus phasellus, est tempor gravida nam, ante '
'fusce sem tempor. Mi diam auctor vel pede, mus '
'non mi luctus luctus, lectus sit varius repellat '
'eu')
long_text = ('Lorem ipsum dolor sit amet, velit eu nam cursus '
'quisque gravida sollicitudin, felis arcu interdum '
'error quam quis massa, et velit libero ligula est '
'donec. Suspendisse fringilla urna ridiculus dui '
'volutpat justo, quisque nisl eget sed blandit '
'egestas, libero nullam magna sem dui nam, auctor '
'vehicula nunc arcu vel sed dictum, tincidunt vitae '
'id tristique aptent platea. Lacus eros nec proin '
'morbi sollicitudin integer, montes suspendisse '
'augue lorem iaculis sed, viverra sed interdum eget '
'ut at pulvinar, turpis vivamus ac pharetra nulla '
'maecenas ut. Consequat dui condimentum lectus nulla '
'vitae, nam consequat fusce ac facilisis eget orci, '
'cras enim donec aenean sed dolor aliquam, elit '
'lorem in a nec fringilla, malesuada curabitur diam '
'nonummy nisl nibh ipsum. In odio nunc nec porttitor '
'ipsum, nunc ridiculus platea wisi turpis praesent '
'vestibulum, suspendisse hendrerit amet quis vivamus '
'adipiscing elit, ut dolor nec nonummy mauris nec '
'libero, ad rutrum id tristique facilisis sed '
'ultrices. Convallis velit posuere mauris lectus sit '
'turpis, lobortis volutpat et placerat leo '
'malesuada, vulputate id maecenas at a volutpat '
'vulputate, est augue nec proin ipsum pellentesque '
'fringilla. Mattis feugiat metus ultricies repellat '
'dictum, suspendisse erat rhoncus ultricies in ipsum, '
'nulla ante pellentesque blandit ligula sagittis '
'ultricies, sed tortor sodales pede et duis platea')
text = random.choice([short_text, medium_text, long_text, long_text])
return '\nFurther info: ' + text
def main_01(wraplength=200):
# alias
stuff = further_text
root = tk.Tk()
frame = ttk.Frame(root)
btn_ne = ttk.Button(frame, text='North East')
btn_se = ttk.Button(frame, text='South East')
btn_sw = ttk.Button(frame, text='South West')
btn_nw = ttk.Button(frame, text='North West')
btn_center = ttk.Button(frame, text='Center')
btn_n = ttk.Button(frame, text='North')
btn_e = ttk.Button(frame, text='East')
btn_s = ttk.Button(frame, text='South')
btn_w = ttk.Button(frame, text='West')
Tooltip(btn_nw, text='North West' + stuff(), wraplength=wraplength)
Tooltip(btn_ne, text='North East' + stuff(), wraplength=wraplength)
Tooltip(btn_se, text='South East' + stuff(), wraplength=wraplength)
Tooltip(btn_sw, text='South West' + stuff(), wraplength=wraplength)
Tooltip(btn_center, text='Center' + stuff(), wraplength=wraplength)
Tooltip(btn_n, text='North' + stuff(), wraplength=wraplength)
Tooltip(btn_e, text='East' + stuff(), wraplength=wraplength)
Tooltip(btn_s, text='South' + stuff(), wraplength=wraplength)
Tooltip(btn_w, text='West' + stuff(), wraplength=wraplength)
r = 0
c = 0
pad = 10
btn_nw.grid(row=r, column=c, padx=pad, pady=pad, sticky=tk.NW)
btn_n.grid(row=r, column=c + 1, padx=pad, pady=pad, sticky=tk.N)
btn_ne.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.NE)
r += 1
btn_w.grid(row=r, column=c + 0, padx=pad, pady=pad, sticky=tk.W)
btn_center.grid(row=r, column=c + 1, padx=pad, pady=pad,
sticky=tk.NSEW)
btn_e.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.E)
r += 1
btn_sw.grid(row=r, column=c, padx=pad, pady=pad, sticky=tk.SW)
btn_s.grid(row=r, column=c + 1, padx=pad, pady=pad, sticky=tk.S)
btn_se.grid(row=r, column=c + 2, padx=pad, pady=pad, sticky=tk.SE)
frame.grid(sticky=tk.NSEW)
for i in (0, 2):
frame.rowconfigure(i, weight=1)
frame.columnconfigure(i, weight=1)
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
root.title('Tooltip wraplength = {}'.format(wraplength))
root.mainloop()
def main():
print('Trying out three different wraplengths:')
for i, wl in enumerate((200, 250, 400), 1):
print(' ', i)
main_01(wl)
print('Done.')
main()
HTH. I posted here a CanvasTooltip class that allows to bind tooltips to items created inside a tkinter Canvas.
Though there are multiple answers, I'll add my 2 cents.
class ToolTip:
def __init__(self,widget,text=None):
def on_enter(event):
self.tooltip=tk.Toplevel()
self.tooltip.overrideredirect(True)
self.tooltip.geometry(f'+{event.x_root+15}+{event.y_root+10}')
self.label=tk.Label(self.tooltip,text=self.text)
self.label.pack()
def on_leave(event):
self.tooltip.destroy()
self.widget=widget
self.text=text
self.widget.bind('<Enter>',on_enter)
self.widget.bind('<Leave>',on_leave)
This is a basic tooltip that will be displayed relative to the position of the cursor.
from tkinter import *
from tkinter.tix import *
root = Tk()
btn1 = Button(root, text="hello")
btn1.grid(row=0, column=0)
balloon = Balloon(root, bg="white", title="Help")
balloon.bind_widget(btn1, balloonmsg="Click to Exit")
root.mainloop()
精彩评论