鼠标悬停时如何更改行颜色? Tkinter 树视图
How to change row color when mouse over? Tkinter Treeview
我最近一直在使用 Tkinter ttk.Treeview 小部件,我已经能够使用 ttk.Style
更改很多小部件的样式,但遗憾的是我找不到解决这个问题的方法问题:
cursor/mouse 结束后如何更改项目的颜色?
喜欢 Tkinter.Button
的 activebackground
选项。
就像 VS CODE 树视图一样:当您浏览资源管理器时,光标下的文件/文件夹会更改背景颜色。
这是一个例子。您可以进一步改进此代码。
import tkinter as tk
from tkinter import ttk
def Enter_event(event):
for x in tree.get_children():
tree.tag_configure(tree.item(x)['tags'], background='')
tree.tag_configure(tree.item(tree.identify_row(event.y))['tags'], background='yellow')
root = tk.Tk()
style = ttk.Style()
style.configure('W.TButton')
tree = ttk.Treeview(root, style = 'W.TButton')
tree.pack()
for i in range(10):
tree.insert("", "end", text="Item %s" % i, tags=i)
tree.tag_bind(i, '<Motion>', Enter_event)
root.mainloop()
解释:
使用为每个单元格设置一个标签,然后将每个标签绑定到运动事件并调用事件处理程序。
tree.item(x)['tags']
returns指定iid的标签。
tree.get_children()
returns 所有 children iid
tree.identify_row(event.y)
returns y 位置的行。
tree.tag_configure(tree.item(tree.identify_row(event.y))['tags'], background='yellow')
将改变指定标签的背景。
我尝试了进入和离开事件,但没有被识别。
(另外,注意设置样式配置为 'Treeview' 对我不起作用。如果对任何读者有用请通知我)
你可以用标签控制一行的颜色,所以解决方案的第一部分是定义一个标签来突出显示一行:
tree.tag_configure('highlight', background='lightblue')
接下来,编写一个方法,从树中的所有项目中删除该标签,然后为光标下的项目添加它。底层的tk widget有添加和删除标签的方法,但是这些方法没有暴露,所以我们需要直接调用底层的tk代码。
def highlight_row(event):
tree = event.widget
item = tree.identify_row(event.y)
tree.tk.call(tree, "tag", "remove", "highlight")
tree.tk.call(tree, "tag", "add", "highlight", item)
最后,将函数绑定到 <Motion>
事件:
tree.bind("<Motion>", highlight_row)
这是一个完整的工作示例:
import tkinter as tk
from tkinter import ttk
def highlight_row(event):
tree = event.widget
item = tree.identify_row(event.y)
tree.tk.call(tree, "tag", "remove", "highlight")
tree.tk.call(tree, "tag", "add", "highlight", item)
root = tk.Tk()
tree = ttk.Treeview(root, style = 'W.TButton')
vsb = ttk.Scrollbar(root, command=tree.yview)
tree.configure(yscrollcommand=vsb.set)
vsb.pack(side="right", fill="y")
tree.pack(side="left", fill="both", expand=True)
tree.tag_configure('highlight', background='lightblue')
tree.bind("<Motion>", highlight_row)
for i in range(100):
tree.insert("", "end", text=f"Item #{i+1}")
tree.tag_bind(i, '<Motion>', highlight_row)
root.mainloop()
我最近一直在使用 Tkinter ttk.Treeview 小部件,我已经能够使用 ttk.Style
更改很多小部件的样式,但遗憾的是我找不到解决这个问题的方法问题:
cursor/mouse 结束后如何更改项目的颜色?
喜欢 Tkinter.Button
的 activebackground
选项。
就像 VS CODE 树视图一样:当您浏览资源管理器时,光标下的文件/文件夹会更改背景颜色。
这是一个例子。您可以进一步改进此代码。
import tkinter as tk
from tkinter import ttk
def Enter_event(event):
for x in tree.get_children():
tree.tag_configure(tree.item(x)['tags'], background='')
tree.tag_configure(tree.item(tree.identify_row(event.y))['tags'], background='yellow')
root = tk.Tk()
style = ttk.Style()
style.configure('W.TButton')
tree = ttk.Treeview(root, style = 'W.TButton')
tree.pack()
for i in range(10):
tree.insert("", "end", text="Item %s" % i, tags=i)
tree.tag_bind(i, '<Motion>', Enter_event)
root.mainloop()
解释:
使用为每个单元格设置一个标签,然后将每个标签绑定到运动事件并调用事件处理程序。
tree.item(x)['tags']
returns指定iid的标签。tree.get_children()
returns 所有 children iidtree.identify_row(event.y)
returns y 位置的行。tree.tag_configure(tree.item(tree.identify_row(event.y))['tags'], background='yellow')
将改变指定标签的背景。
我尝试了进入和离开事件,但没有被识别。 (另外,注意设置样式配置为 'Treeview' 对我不起作用。如果对任何读者有用请通知我)
你可以用标签控制一行的颜色,所以解决方案的第一部分是定义一个标签来突出显示一行:
tree.tag_configure('highlight', background='lightblue')
接下来,编写一个方法,从树中的所有项目中删除该标签,然后为光标下的项目添加它。底层的tk widget有添加和删除标签的方法,但是这些方法没有暴露,所以我们需要直接调用底层的tk代码。
def highlight_row(event):
tree = event.widget
item = tree.identify_row(event.y)
tree.tk.call(tree, "tag", "remove", "highlight")
tree.tk.call(tree, "tag", "add", "highlight", item)
最后,将函数绑定到 <Motion>
事件:
tree.bind("<Motion>", highlight_row)
这是一个完整的工作示例:
import tkinter as tk
from tkinter import ttk
def highlight_row(event):
tree = event.widget
item = tree.identify_row(event.y)
tree.tk.call(tree, "tag", "remove", "highlight")
tree.tk.call(tree, "tag", "add", "highlight", item)
root = tk.Tk()
tree = ttk.Treeview(root, style = 'W.TButton')
vsb = ttk.Scrollbar(root, command=tree.yview)
tree.configure(yscrollcommand=vsb.set)
vsb.pack(side="right", fill="y")
tree.pack(side="left", fill="both", expand=True)
tree.tag_configure('highlight', background='lightblue')
tree.bind("<Motion>", highlight_row)
for i in range(100):
tree.insert("", "end", text=f"Item #{i+1}")
tree.tag_bind(i, '<Motion>', highlight_row)
root.mainloop()