Search code examples
python-3.xtkintertreeview

Duplicating a Tkinter treeview


I'm trying to display a ttk treeview in another window. The only option, it seems, is to iterate through the original treeview and populate the new one accordingly.

However I can't seem to get all the (many) subfolders in the right place, everything is mixed up as of the 2d level (i.e., I get the root folders and their children right, and after that the subfolders seem to be inserted at random locations).

The function is :

    def getsubchildren(item=''):
        children = []
        for child in original_treeview.get_children(item):
            i = new_treeview.insert(item, 'end', text=original_treeview.item(child) 
                                   ['text'],values=original_treeview.item(child)['values'])
            children.append(i)

        for subchild in children: 
            getsubchildren(subchild)

And calling the function with getsubchildren(item=''), to start iterating from the first level. There must be something I'm doing wrong, but I can't identify the issue and my attempts at modifying the function have only given a poorer result. Any idea ?

Thanks,


Solution

  • Without known the depth of the item you need to check if the item has children. If so you need the function to call itself in a loop. Here is a working exampel:

    import tkinter as tk
    from tkinter import ttk
    
    root = tk.Tk()
    
    maintree = ttk.Treeview(root)
    maintree.pack()
    
    first = maintree.insert("","end",text='first')
    second= maintree.insert(first,"end",text='second')
    third= maintree.insert(second,"end",text='third')
    fourth= maintree.insert(third,"end",text='fourth')
    
    st = maintree.insert("","end",text='1st')
    nd= maintree.insert(st,"end",text='2nd')
    rd= maintree.insert(nd,"end",text='3rd')
    th= maintree.insert(rd,"end",text='4th')
    
    top = tk.Toplevel(root)
    subtree = ttk.Treeview(top)
    subtree.pack()
    
    def copy_item_tree(item,child):
        for child in maintree.get_children(child):
            item = subtree.insert(item,"end",
                                  text=maintree.item(child)['text'])
            if maintree.get_children(child):
                copy_item_tree(item,child)
    def copy_tree():
        for child in maintree.get_children():
            item = subtree.insert("","end",text=maintree.item(child)['text'])
            copy_item_tree(item,child)
    
    button = tk.Button(root,text='Copy Tree', command=copy_tree)
    button.pack(fill='x')
    root.mainloop()