2017-01-25 2 views
2

Я создал виджет ttk/Treeview в Tkinter с помощью Python 3. Я хотел бы связать объект с его именем, которое указано в древовидном представлении. Чтобы проиллюстрировать это, я создал следующий пример.Подключить объект к элементу в виджетах Treeview

import tkinter as tk 
from tkinter import ttk 

class myclass: 
    def __init__(self, name, value): 
     self.name=name 
     self.value=value 

class maintree(ttk.Treeview): 
    def __init__(self, master):   
     super().__init__(master) 
     self.master = master 
     self.my_objects= [myclass("object"+str(_), _) for _ in range(1,11)] 
     for my_object in self.my_objects: 
      self.insert("", "end", text=my_object.name) 

def main(): 
    root = tk.Tk() 
    maintree(root).grid() 
    root.mainloop() 

if __name__ == '__main__': 
    main() 

В этом примере я хотел бы получить my_class экземпляр, соответствующий выбранному имени в TreeView, чтобы сделать что-то (т.е. отобразить значение выбранного объекта my_class).

Я знаю только об идентификаторах элементов, но я не знаю, как соединить что-то с самим предметом. У меня такое ощущение, что у меня есть неправильное представление о том, как должно работать дерево.

Я ценю вашу помощь!

ответ

1

insert способ не имеет command опция. Тем не менее, вы можете пометить каждый вставленный элемент и привязать тег к событию. Таким образом, я использовал имя объекта как тег, а затем привязал его к выполнению какого-либо метода объекта на левом щелчке мыши.

import tkinter as tk 
from tkinter import ttk 

class MyClass: 
    def __init__(self, name, value): 
     self.name=name 
     self.value=value 

    def callback(self, event=None): 
     # event=None is a trick to be able to call the method both directly and 
     # from a binding (that will pass the event argument to the function) 
     print(self.name, self.value) 

class MainTree(ttk.Treeview): 
    def __init__(self, master):   
     super().__init__(master) 
     self.master = master 
     self.my_objects= [MyClass("object"+str(_), _) for _ in range(1,11)] 
     for my_object in self.my_objects: 
      self.insert("", "end", text=my_object.name, tags=(my_object.name,)) 
      self.tag_bind(my_object.name, '<Button-1>', my_object.callback) 

def main(): 
    root = tk.Tk() 
    MainTree(root).grid() 
    root.mainloop() 

if __name__ == '__main__': 
    main() 
+0

Во-первых: Большое спасибо! Далее. Могу ли я расширить этот метод, чтобы обрабатывать изменения выбора другим способом (например, с помощью клавиш со стрелками)? – Benjamin

+0

Я использую 'id (my_object)' для имени тега сейчас, так как это дает мне уникальный идентификатор для каждого объекта. Также добавление 'self.tag_bind (id (my_object), '', my_object.callback)' после строки 'self.tag_bind ... 'позволяет выполнять обратный вызов с помощью клавиатуры, которая приближается к тому, что я просил в моем предыдущий комментарий. – Benjamin

+1

Изучив свойства виджета Treeview, я нашел на http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-Treeview-events.html, что «всякий раз, когда происходят изменения в выбор, либо с помощью элементов, которые становятся выбранными, либо становятся невыбранными, виджет генерирует событие «<< TreeviewSelect >>». Поэтому замена «» на «<< TreeviewSelect >>» должна делать то, что вы хотите. –