如何在Tkinter中显示工具提示?
工具提示是一种非常有用的用户界面辅助功能,可以在用户将鼠标悬停在控件上时提供额外的信息或指导。在Tkinter中,可以使用标准库中的ttk
模块来创建工具提示。
创建工具提示
要创建工具提示,需要使用ttk
模块中的ToolTip
类。下面是一个简单的示例:
import tkinter as tk
from tkinter import ttk
class ToolTip:
def __init__(self, widget, text):
self.widget = widget
self.tooltip = None
self.text = text
self.widget.bind('<Enter>', self.show_tooltip)
self.widget.bind('<Leave>', self.hide_tooltip)
def show_tooltip(self, event):
x, y, cx, cy = self.widget.bbox('insert')
x = x + self.widget.winfo_rootx() + 25
y = y + cy + self.widget.winfo_rooty() + 25
self.tooltip = tk.Toplevel(self.widget)
self.tooltip.overrideredirect(True)
self.tooltip.geometry('+{}+{}'.format(x, y))
label = tk.Label(self.tooltip, text=self.text, justify='left', background='#ffffe0', relief='solid', borderwidth=1, font=('tahoma', '8', 'normal'))
label.pack(ipadx=1)
def hide_tooltip(self, event):
if self.tooltip:
self.tooltip.destroy()
self.tooltip = None
在这个示例中,ToolTip
类以一个要添加工具提示的控件和要显示的文本作为参数进行初始化。show_tooltip
方法创建一个Toplevel
对象来显示工具提示,该对象的位置在控件的下方和右侧字形边界的偏移量上,它的overrideredirect
方法设置为True
,以隐藏窗口边框和标题栏。label
小部件包含显示的文本,并放置在工具提示窗口内。
hide_tooltip
方法在鼠标移开时销毁工具提示窗口。
现在我们可以测试一下这个工具提示:
root = tk.Tk()
root.geometry('300x300')
button1 = ttk.Button(root, text='Button with Tooltip')
button1.pack(padx=50, pady=50)
tip = ToolTip(button1, 'This is a tooltip for button1')
root.mainloop()
改进工具提示
现在我们已经创建了一个基本的工具提示,但还有一些改进的余地。例如,我们可以添加一个延迟,在用户只悬停在控件上一段时间后才显示工具提示。
为增加延迟,我们需要使用after
方法。首先,我们在__init__
方法中定义延迟时间,并在show_tooltip
方法中启动一个定时器,一旦延迟时间过去,就显示工具提示:
class ToolTip:
def __init__(self, widget, text, delay=750):
self.widget = widget
self.tooltip = None
self.text = text
self.delay = delay
self.widget.bind('<Enter>', self.start_timer)
self.widget.bind('<Leave>', self.stop_timer)
def start_timer(self, event):
self.timer_id = self.widget.after(self.delay, self.show_tooltip)
def stop_timer(self, event):
if self.timer_id:
self.widget.after_cancel(self.timer_id)
self.timer_id = None
def show_tooltip(self):
x, y, cx, cy = self.widget.bbox('insert')
x = x + self.widget.winfo_rootx() + 25
y = y + cy + self.widget.winfo_rooty() + 25
self.tooltip = tk.Toplevel(self.widget)
self.tooltip.overrideredirect(True)
self.tooltip.geometry('+{}+{}'.format(x, y))
label = tk.Label(self.tooltip, text=self.text, justify='left', background='#ffffe0', relief='solid', borderwidth=1, font=('tahoma', '8', 'normal'))
label.pack(ipadx=1)
def hide_tooltip(self, event):
if self.tooltip:
self.tooltip.destroy()
self.tooltip = None
这里我们使用after
方法来创建一个定时器,当悬停在控件上self.delay
毫秒后调用show_tooltip
方法。start_timer
方法启动定时器,stop_timer
方法停止定时器。timer_id
是用于存储计时器标识符的变量。
除此之外,我们还可以添加一些其他的改进,例如,我们可以使用样式来美化工具提示。可以使用style
方法从一个样式名称初始化ToolTip
。我们需要在样式中定义一个Label
部件,以指示工具提示的样式。
我们还可以使用update
方法来获取小部件的屏幕尺寸,以适当地定位、调整大小和显示工具提示。下面是一个改进后的代码示例:
class ToolTip:
def __init__(self, widget, text, style='ToolTip.TLabel', delay=750):
self.widget = widget
self.tooltip = None
self.text = text
self.delay = delay
self.widget.bind('<Enter>', self.start_timer)
self.widget.bind('<Leave>', self.stop_timer)
self.style = ttk.Style()
self.style.configure(style, background='#ffffe0', relief='solid', borderwidth=1, font=('tahoma', '8', 'normal'))
def start_timer(self, event):
self.timer_id = self.widget.after(self.delay, self.show_tooltip)
def stop_timer(self, event):
if self.timer_id:
self.widget.after_cancel(self.timer_id)
self.timer_id = None
def show_tooltip(self):
if self.tooltip:
return
x, y, cx, cy = self.widget.bbox('insert')
x = x + self.widget.winfo_rootx() + 25
y = y + cy + self.widget.winfo_rooty() + 25
self.tooltip = tk.Toplevel(self.widget, takefocus=True)
self.tooltip.overrideredirect(True)
self.tooltip.geometry('1x1+'+str(x)+'+'+str(y)+'')
self.tooltip.update_idletasks()
width, height = self.tooltip.winfo_reqwidth(), self.tooltip.winfo_reqheight()
screen_width = self.tooltip.winfo_screenwidth()
if x + width > screen_width:
x = screen_width - width
self.tooltip.geometry('{}x{}+{}+{}'.format(width, height, x, y))
label = ttk.Label(self.tooltip, text=self.text, style=self.style)
label.pack(ipadx=1, ipady=1)
self.tooltip.lift()
def hide_tooltip(self, event):
if self.tooltip:
self.tooltip.destroy()
self.tooltip = None
这一次,我们使用了一个默认的样式ToolTip.TLabel
,使用self.style
来初始化样式。show_tooltip
方法使用update_idletasks
方法获取小部件的屏幕尺寸,以便适当地定位窗口。
我们还使用了lift
方法将工具提示推动到前台,避免因其他小部件覆盖工具提示而使它无法完全显示。
现在,我们可以测试这个新的ToolTip
类:
root = tk.Tk()
root.geometry('300x300')
style = ttk.Style()
style.configure('ToolTip.TLabel', background='#f7f7f7', foreground='red')
button1 = ttk.Button(root, text='Button with Tooltip')
button1.pack(padx=50, pady=50)
tip = ToolTip(button1, 'This is an improved tooltip', style='ToolTip.TLabel')
root.mainloop()
运行这个示例,我们可以看到,当将鼠标悬停在按钮上时,会显示一个漂亮的工具提示,并且具有一种更好的外观。
结论
在Tkinter中,我们可以使用ttk
模块中的ToolTip
类来轻松创建工具提示。我们可以使用after
方法来增加一个延迟,使用update
方法来获取小部件的屏幕尺寸并将工具提示定位在正确的位置。我们还可以使用style
来定义工具提示的样式,使其更美观。
如果你是一个使用Tkinter的开发者,你绝对会发现这个小部件非常有用,因为它可以使你的用户更容易理解你的应用程序。现在,你已经知道了如何创建一个定制的工具提示,为用户提供更好的用户体验。