Search code examples
pythontkinterttk

Connect an Object to an item in a Treeview Widget


I created a ttk/Treeview Widget in Tkinter using Python 3. I would like to connect an object to its name which is listed in the tree view. To illustrate this I created following example.

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() 

In this example I would like to get the my_class instance corresponding to the selected name in the treeview to do something (ie, display the value of the currently selected my_class object).

I only know about the item IDs but I don't know how to connect something to an item itself. I have the feeling that I have some misconception about how treeview is supposed to work.

I appreciate your Help!


Solution

  • The insert method has no command option. However, you can tag each inserted item and bind the tag to an event. So, I used the object name as tag and then bound it to execute some method of the object on mouse left click.

    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()