Hovertip/Tooltip 对于 Python ttk 组合框中的每个项目
Hovertip/Tooltip for each item in Python ttk combobox
这是关于 ttk 组合框的。
我需要通过工具提示为 ttk.combobox 中的每个项目(文本)显示帮助信息。
最小示例如下:
import tkinter as tk
from tkinter import ttk
from idlelib.tooltip import Hovertip
names =["One", "Two", "Three"]
root = tk.Tk()
root.title("Combo Test GUI")
Frame1 = ttk.Frame(root, padding="3 3 12 12")
Frame1.grid(column= 0, row = 0)
label_1 = ttk.Label(Frame1, text="Select Item:", anchor=tk.W)
label_1.grid(column= 0, row = 1)
item1 = ttk.Combobox(Frame1, state="readonly", values=names, width=35)
item1.grid(column= 0, row = 2)
m1 = Hovertip(item1, "One test")
m2 = Hovertip(label_1, "Another test")
root.mainloop()
问题:我想将 Hovertip 绑定到组合列表中的文本,即“一”、“二”、“三”。
当用户将鼠标悬停在“一”上时,Hovertip/Tooltip 中应显示“这是选项一”的描述;其他项目“二”和“三”也一样。
我到处搜索,在 Whosebug 上,在参考文档中,其他网站上,但似乎 Hovertip/Tooltip 只能与小部件一起使用,而不能与组合框中的简单文本一起使用。
有没有办法让它成为可能?
我们的想法是制作一个类似于 Hovertip
的 class,但它适用于列表框项目而不是小部件。当前项目存储在 self._current_item
中,当鼠标在列表框中移动时,如果项目发生变化,工具提示的显示将重新安排。每个项目的文本存储在字典 self.tips = {item index: text, ...}
.
中
主要问题是 Listbox
显示 Combobox
的选择不能直接通过 python 访问。所以我不得不使用一些 Tcl 命令来完成它:
proc callback {y} {
event generate .!combobox <<OnMotion>> -y $y
}
set popdown [ttk::combobox::PopdownWindow .!combobox]
bind $popdown.f.l <Motion> {callback %y}
上面的代码在鼠标移动时在组合框中生成一个虚拟事件<<OnMotion>>
(其中.!combobox
是Combobox
小部件的名称,y
是小部件中的鼠标相对 y 坐标)。
然后我将组合框的 _on_motion()
方法绑定到此 <<OnMotion>>
事件以检查当前项目是否已更改。要获取当前项,我使用 Listbox
方法 nearest(y)
但来自 Tcl.
我还修改了 get_position()
方法以在当前项目下方显示工具提示,并修改 showcontents()
以显示与项目对应的文本。
完整代码如下:
import tkinter as tk
from tkinter import ttk
from idlelib.tooltip import OnHoverTooltipBase
class ComboboxTip(OnHoverTooltipBase):
def __init__(self, combobox_widget, hover_delay=1000):
super(ComboboxTip, self).__init__(combobox_widget, hover_delay=hover_delay)
self.tips = {}
self._current_item = 0
combobox_widget.tk.eval("""
proc callback {y} {
event generate %(cb)s <<OnMotion>> -y $y
}
set popdown [ttk::combobox::PopdownWindow %(cb)s]
bind $popdown.f.l <Motion> {callback %%y}
""" % ({"cb": combobox_widget}))
self._id4 = combobox_widget.bind("<<OnMotion>>", self._on_motion)
def _on_motion(self, event):
current_item = int(self.anchor_widget.tk.eval("$popdown.f.l nearest %i" % event.y))
if current_item != self._current_item:
self._current_item = current_item
self.hidetip()
if current_item in self.tips:
self.schedule()
else:
self.unschedule()
def __del__(self):
try:
self.anchor_widget.unbind("<<OnMotion>>", self._id4)
except tk.TclError:
pass
super(ComboboxTip, self).__del__()
def add_tooltip(self, index, text):
self.tips[index] = text
def get_position(self):
"""choose a screen position for the tooltip"""
try:
h = self.anchor_widget.winfo_height()
bbox = self.anchor_widget._getints(self.anchor_widget.tk.eval("$popdown.f.l bbox %i" % self._current_item))
return bbox[0] + bbox[2], bbox[1] + bbox[-1] + h
except Exception:
return 20, self.anchor_widget.winfo_height() + 1
def showcontents(self):
label = tk.Label(self.tipwindow, text=self.tips[self._current_item], justify=tk.LEFT,
background="#ffffe0", relief=tk.SOLID, borderwidth=1)
label.pack()
names = ["One", "Two", "Three"]
root = tk.Tk()
cb = ttk.Combobox(root, values=names)
cb.pack()
t = ComboboxTip(cb)
t.add_tooltip(0, "This is One")
t.add_tooltip(1, "This is Two")
t.add_tooltip(2, "This is Three")
root.mainloop()
这是关于 ttk 组合框的。 我需要通过工具提示为 ttk.combobox 中的每个项目(文本)显示帮助信息。
最小示例如下:
import tkinter as tk
from tkinter import ttk
from idlelib.tooltip import Hovertip
names =["One", "Two", "Three"]
root = tk.Tk()
root.title("Combo Test GUI")
Frame1 = ttk.Frame(root, padding="3 3 12 12")
Frame1.grid(column= 0, row = 0)
label_1 = ttk.Label(Frame1, text="Select Item:", anchor=tk.W)
label_1.grid(column= 0, row = 1)
item1 = ttk.Combobox(Frame1, state="readonly", values=names, width=35)
item1.grid(column= 0, row = 2)
m1 = Hovertip(item1, "One test")
m2 = Hovertip(label_1, "Another test")
root.mainloop()
问题:我想将 Hovertip 绑定到组合列表中的文本,即“一”、“二”、“三”。
当用户将鼠标悬停在“一”上时,Hovertip/Tooltip 中应显示“这是选项一”的描述;其他项目“二”和“三”也一样。
我到处搜索,在 Whosebug 上,在参考文档中,其他网站上,但似乎 Hovertip/Tooltip 只能与小部件一起使用,而不能与组合框中的简单文本一起使用。
有没有办法让它成为可能?
我们的想法是制作一个类似于 Hovertip
的 class,但它适用于列表框项目而不是小部件。当前项目存储在 self._current_item
中,当鼠标在列表框中移动时,如果项目发生变化,工具提示的显示将重新安排。每个项目的文本存储在字典 self.tips = {item index: text, ...}
.
主要问题是 Listbox
显示 Combobox
的选择不能直接通过 python 访问。所以我不得不使用一些 Tcl 命令来完成它:
proc callback {y} {
event generate .!combobox <<OnMotion>> -y $y
}
set popdown [ttk::combobox::PopdownWindow .!combobox]
bind $popdown.f.l <Motion> {callback %y}
上面的代码在鼠标移动时在组合框中生成一个虚拟事件<<OnMotion>>
(其中.!combobox
是Combobox
小部件的名称,y
是小部件中的鼠标相对 y 坐标)。
然后我将组合框的 _on_motion()
方法绑定到此 <<OnMotion>>
事件以检查当前项目是否已更改。要获取当前项,我使用 Listbox
方法 nearest(y)
但来自 Tcl.
我还修改了 get_position()
方法以在当前项目下方显示工具提示,并修改 showcontents()
以显示与项目对应的文本。
完整代码如下:
import tkinter as tk
from tkinter import ttk
from idlelib.tooltip import OnHoverTooltipBase
class ComboboxTip(OnHoverTooltipBase):
def __init__(self, combobox_widget, hover_delay=1000):
super(ComboboxTip, self).__init__(combobox_widget, hover_delay=hover_delay)
self.tips = {}
self._current_item = 0
combobox_widget.tk.eval("""
proc callback {y} {
event generate %(cb)s <<OnMotion>> -y $y
}
set popdown [ttk::combobox::PopdownWindow %(cb)s]
bind $popdown.f.l <Motion> {callback %%y}
""" % ({"cb": combobox_widget}))
self._id4 = combobox_widget.bind("<<OnMotion>>", self._on_motion)
def _on_motion(self, event):
current_item = int(self.anchor_widget.tk.eval("$popdown.f.l nearest %i" % event.y))
if current_item != self._current_item:
self._current_item = current_item
self.hidetip()
if current_item in self.tips:
self.schedule()
else:
self.unschedule()
def __del__(self):
try:
self.anchor_widget.unbind("<<OnMotion>>", self._id4)
except tk.TclError:
pass
super(ComboboxTip, self).__del__()
def add_tooltip(self, index, text):
self.tips[index] = text
def get_position(self):
"""choose a screen position for the tooltip"""
try:
h = self.anchor_widget.winfo_height()
bbox = self.anchor_widget._getints(self.anchor_widget.tk.eval("$popdown.f.l bbox %i" % self._current_item))
return bbox[0] + bbox[2], bbox[1] + bbox[-1] + h
except Exception:
return 20, self.anchor_widget.winfo_height() + 1
def showcontents(self):
label = tk.Label(self.tipwindow, text=self.tips[self._current_item], justify=tk.LEFT,
background="#ffffe0", relief=tk.SOLID, borderwidth=1)
label.pack()
names = ["One", "Two", "Three"]
root = tk.Tk()
cb = ttk.Combobox(root, values=names)
cb.pack()
t = ComboboxTip(cb)
t.add_tooltip(0, "This is One")
t.add_tooltip(1, "This is Two")
t.add_tooltip(2, "This is Three")
root.mainloop()