Treeview

A treeview widget can display a hierarchy of items. The items are organized in the form of a tree. The parent node is '' and is not displayed. Within a node the items are indexed: 0 being the first item, 'end' representing the position after the last item.

To insert an item to t treeview use the function:

tree.insert(node, index, name, text='Label')

The first example creates a treeview, adds an item at position 0, and another item at position end. The id of the third item is assigned to a local variable in order to use it as a node for creating to sub-items.

../_images/tree0.png
from tklib import *
app = App('Treeview')

tree = ttk.Treeview(App.stack[-1])
tree.grid()
tree.insert('', 0, text='Item 1')
tree.insert('', 'end', text='Item 2')

id = tree.insert('', 5, text='Item 3')
tree.insert(id, 0, text='sub-item 0')
tree.insert(id, 1, text='sub-item 1')
app.run()

tree0.py

Multiple columns

The option tree['columns'] adds more columns:

tree['columns'] = ('size', 'modified')

The width, alignment and label of a column can further be specified. To insert values to the new columns use the method set:

tree.set('widgets', 'size', '12KB')
tree.set('widgets', 'modified', 'Last week')

To insert all values at creation use the option values:

tree.insert('', 'end', text='Listbox', values=('15KB Yesterday'))
../_images/tree1_col.png
from tklib import *
app = App('Treeview - multiple columns')

tree = ttk.Treeview(App.stack[-1])
tree.grid()

tree.insert('', 'end', 'widgets', text='Widgets')
tree.insert('', 0, 'apps', text='Applications')

tree['columns'] = ('size', 'modified')
tree.column('size', width=50, anchor='center')
tree.heading('size', text='Size')
tree.heading('modified', text='Modified')

tree.set('widgets', 'size', '12KB')
tree.set('widgets', 'modified', 'Last week')

tree.insert('', 'end', text='Canvas', values=('25KB Today'))
tree.insert('apps', 'end', text='Browser', values=('115KB Yesterday'))

app.run()

tree1_col.py

Configure style

Like the text and canvas widgets, the Treeview widget uses tags to modify the appearance of lines. Tags are simply a list of strings, such as:

tree.insert('', 'end', text='Item 4', tags=('fg', 'bg'))

Configure the tag with background and foreground color:

tree.tag_configure('bg', background='yellow')
tree.tag_configure('fg', foreground='red')
../_images/tree1_tag.png
from tklib import *
app = App('Treeview - tags')

tree = ttk.Treeview(App.stack[-1])
tree.grid()

tree.insert('', 'end', text='Item 1', tags=('fg'))
tree.insert('', 'end', text='Item 2', tags=('bg'))
tree.insert('', 'end', text='Item 2')
tree.insert('', 'end', text='Item 4', tags=('fg', 'bg'))

tree.tag_configure('bg', background='yellow')
tree.tag_configure('fg', foreground='red')

app.run()

tree1_tag.py

Bind to events

Tags are also used to bind lines to events. This adds a callback to the button click:

tree.tag_bind('cb', '<1>', cb)

This adds 3 virtual events:

tree.tag_bind('cb', '<<TreeviewSelect>>', cb)
tree.tag_bind('cb', '<<TreeviewOpen>>', cb)
tree.tag_bind('cb', '<<TreeviewClose>>', cb)

In the callback function cb we print the event, the selection and the focus:

def cb(event):
    print(event, tree.selection(), tree.focus())

Something like this will be printed to the console:

<ButtonPress event num=1 x=8 y=46> ('I002',) I002
<VirtualEvent event x=0 y=0> ('I002',) I002
<VirtualEvent event x=0 y=0> ('I002',) I002
../_images/tree1_bind.png
from tklib import *
app = App('Treeview - bind')

def cb(event):
    print(event, tree.selection(), tree.focus())

tree = ttk.Treeview(App.stack[-1])
tree.grid()

tree.insert('', 'end', text='Item 1', tags=('cb'))
id = tree.insert('', 'end', text='Item 2', tags=('cb'))
tree.insert(id, 'end', text='Sub-Item 1', tags=('cb'))
tree.insert(id, 'end', text='Sub-Item 2', tags=('cb'))

tree.tag_bind('cb', '<1>', cb)
tree.tag_bind('cb', '<<TreeviewSelect>>', cb)
tree.tag_bind('cb', '<<TreeviewOpen>>', cb)
tree.tag_bind('cb', '<<TreeviewClose>>', cb)

app.run()

tree1_bind.py

Two treeviews next to each other

../_images/tree2.png
from tklib import *

app = App('Treeview')

items = dir(tk)
tree = Treeview()
tree['columns'] = ('type', 'value')
tree.column('type', width=100)
tree.heading('type', text='Type')
tree.heading('value', text='Value')

for item in items:
    x = eval('tk.'+item)
    t = type(x)
    print(t.__name__, x)
    tree.insert('', 'end', text=item, values=(t.__name__, x))

items = dir()
Treeview(items).grid(row=0, column=1)

app.run()

tree2.py

Display a 2D table

../_images/tree4.png
"""Display a 2D table."""

from tklib import *
import random

n, m = 40, 10
table = []
for i in range(n):
    line = []
    for j in range(m):
        line.append(random.randint(0, 999))
    table.append(line)


class Demo(App):
    def __init__(self): 
        super().__init__()
        Label('Display a 2D table', font='Arial 24')
        Label('Click on header to sort')
        Combobox('A;B;C')
        
        tree = Treeview()
        for i in range(n):
            tree.insert('', 'end', text=table[i][0], values=table[i][1:])

        tree['columns'] = list(range(m-1))
        headings=list('ABCDEFGHI')
        for j in range(m-1):
            tree.column(j, width=50, anchor='e')
            tree.heading(j, text=headings[j])

if __name__ == '__main__':
    Demo().run()

tree4.py

Insert items into a treeview

../_images/tree5.png
"""Insert items to the tree."""

from tklib import *

class Demo(App):
    def __init__(self): 
        super().__init__()
        Label('Insert items to the tree', font='Arial 24')
        
        App.text = Entry('Text', 'print(self.val.get())')
        App.index = Spinbox('Index', 'print(self.val.get())', to=100)
        
        Button('Insert', 'App.tree.insert("", App.index.val.get(), text=App.text.get())')
        Button('Insert to Folder', 'App.tree.insert("folder", App.index.val.get(), text=App.text.get())')

        App.tree = Treeview()

        L = 'Hello;Dolly;How;Are;You'.split(';')
        for item in L:
            App.tree.insert('', 'end', text=item)
        App.tree.insert('', 0, 'folder', text='Folder')
  
if __name__ == '__main__':
    Demo().run()

tree5.py

Add items to specific column

../_images/tree6.png
"""Insert multiple columns to the tree."""

from tklib import *

class Demo(App):
    def __init__(self): 
        super().__init__()
        Label('Columns', font='Arial 24')
         
        App.tree = Treeview()
        # App.tree['columns'] = ('size', 'date', 'type')
        App.tree['columns'] = range(3)

        App.text = Entry('Text', 'print(self.val.get())')
        App.row = Spinbox('Row:', 'print(self.val.get())', to=100)
        App.col = Spinbox('Column:',  'print(self.val.get())', to=100)
        Button('Set', 'App.tree.set(App.tree.focus(), App.col.val.get(), App.text.get())')

        for i in range(2):
            App.tree.column(i, width=100, anchor='w')
            App.tree.heading(i, text='Heading' + str(i))

        L = 'Hello;Dolly;How;Are;You'.split(';')
        for item in L:
            App.tree.insert('', 'end', text=item)
  
if __name__ == '__main__':
    Demo().run()

tree6.py

Customize the treeview widget

../_images/tree7.png
"""Custumize the Treeview widget."""

from tklib import *

class Demo(App):
    def __init__(self): 
        super().__init__()
        Label('Customizing the Treeview widget', font='Arial 24')
        
        App.tree = Treeview()
        App.tree['columns'] = range(3)

        Spinbox('height=', 'App.tree["height"]=self.var.get()', to=20)
        Spinbox('width=', 'App.tree.column("#0", width=self.var.get())', inc=50, to=500)
        Spinbox('width 0=:', 'App.tree.column(0, width=self.var.get())', inc=50, to=500)
        Spinbox('width 1=:', 'App.tree.column(1, width=self.var.get())', inc=50, to=500)
        Combobox('selectmode=', 'browse;extended;none', 'App.tree["selectmode"]=self.var.get()')
        Button('show tree', "App.tree['show']='tree'")
        Button('show headings', "App.tree['show']='headings'")
        Checkbutton('tree;headings')
        
        for i in range(2):
            App.tree.column(i, width=100, anchor='w')
            App.tree.heading(i, text='Heading' + str(i))

        L = 'Hello;Dolly;How;Are;You'.split(';')
        for item in L:
            App.tree.insert('', 'end', text=item)
  
if __name__ == '__main__':
    Demo().run()

tree7.py