Как изменить цвет строки при наведении курсора? Ткинтер Древовидное представление

В последнее время я работаю с виджетом Tkinter ttk.Treeview, и мне удалось сильно изменить стиль виджета с помощью ttk.Style, но, к сожалению, я не могу найти решение этой проблемы:

Как я могу изменить цвет элемента, когда курсор/мышь наведены?

Как вариант activebackground для Tkinter.Button. Как и в древовидном представлении VS CODE: когда вы перемещаетесь по проводнику, файл/папка под курсором меняет цвет фона.


person Dreamcazzter    schedule 07.01.2021    source источник
comment
Events может помочь   -  person SNR    schedule 07.01.2021
comment
Это виртуальные события, доступные для структуры ttk.Treeview: anzeljg.github.io/rin2/book2/2405/docs/tkinter/ — Кроме того, вы можете использовать события <Enter> и <Leave> для создания эффектов при наведении курсора на что-либо.   -  person oskros    schedule 07.01.2021
comment
Существует также событие под названием <B1-Motion>, которое активируется всякий раз, когда вы двигаете мышью.   -  person oskros    schedule 07.01.2021
comment
Нашел для вас решение: python-forum.io/Thread- bind-hover-on-tkinter-ttk-Treeview   -  person oskros    schedule 07.01.2021


Ответы (2)


Вы можете управлять цветом строки с помощью тега, поэтому первая часть решения заключается в определении тега для выделения строки:

tree.tag_configure('highlight', background='lightblue')

Затем напишите метод, который удалит этот тег из всех элементов в дереве, а затем добавит его для элемента под курсором. Базовый виджет tk имеет методы для добавления и удаления тегов, но эти методы не доступны, поэтому нам нужно будет напрямую вызывать базовый код 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()

скриншот

person Bryan Oakley    schedule 07.01.2021
comment
Да, он работает полностью, как я и предполагал! Благодарю вас! - person Dreamcazzter; 08.01.2021
comment
Это довольно изящно. Есть ли у вас другие опубликованные ответы, в которых более подробно рассказывается о tree = event.widget, за которым следует tree.tk.call(tree...? Я хотел бы изучить, какие еще функции могут быть. - person WinEunuuchs2Unix; 18.07.2021

Вот пример, как это сделать. Вы можете дополнительно улучшить этот код.

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'] возвращает тег указанного iid.

  • tree.get_children() возвращает все дочерние iid

  • tree.identify_row(event.y) возвращает строку в позиции y.

  • tree.tag_configure(tree.item(tree.identify_row(event.y))['tags'], background='yellow') изменит фон указанного тега.

Я пробовал войти и выйти из события, но оно не распознается. (Кроме того, стиль настройки примечания, настроенный на «Treeview», не работает для меня. Если это работает для кого-либо из читателей, пожалуйста, сообщите мне)

person JacksonPro    schedule 07.01.2021