Estou escrevendo um aplicativo de arrastar e soltar onde arrasto dados de uma visualização em árvore para um widget de entrada. Quero poder usar o item da árvore que está sob o cursor quando o botão do mouse é pressionado.
Posso ver como obter o item selecionado, mas ele não é devolvido no momento do evento
Existe alguma maneira de devolver o item?
import tkinter as tk
from tkinter import ttk
def main() -> None:
root = tk.Tk()
root.title('Tree coords')
tree = ttk.Treeview(root, height=30, show='headings',)
tree.grid(row=0, column=0, sticky=tk.NSEW)
tree.bind("<ButtonPress-1>", on_start)
col_list = ('Names', 'Names', 30)
tree['columns'] = col_list
for name in ['ab', 'ef', 'mn']:
values = (name)
tree.insert('', 'end', values=values)
root.mainloop()
def on_start(event=None):
widget = event.widget
selected_items = widget.selection()
x, y = event.widget.winfo_pointerxy()
print(x, y, selected_items)
if __name__ == '__main__':
main()
O problema é que sua ligação é chamada antes de
treeview
ser atualizada. Astreeview
ligações de classe acontecem depois das ligações específicas do widget, então aselection()
função retornará o item selecionado anteriormente. Uma maneira de consertar isso é criar a ligação depois das ligações de classe (veja aqui para mais informações).Você também pode fazer a vinculação para
"<<TreeviewSelect>>"
em vez de"<ButtonPress-1>"
, mas ela pode ser acionada não apenas pelo botão do mouse (por exemplo, pelas teclas "Para cima" ou "Para baixo").Uma terceira maneira é usar uma função que pode funcionar quase independentemente da
treeview
ligação de classe. Por exemplo, você pode usar oidentify_row
método para obter o item em alguma posição Y. No seu caso, basta substituirselected_items = widget.selection()
porselected_items = widget.identify_row(event.y)
. Embora esta não seja uma substituição exata, já que oidentify_row()
método sempre retorna apenas um elemento, enquanto oselection()
método pode retornar vários elementos.