Tkinter Treeview Parent-Child Nodes using iid, parent and open

A Tkinter Treeview can store items in a hierarchy. A top-level item can contain child items, and those children can contain further descendants.

The relationship is created through the first argument of insert(). An empty string creates a top-level item. Passing another item's iid creates a child under that item.


Tkinter Treeview Parent and Child Rows using insert()

Parent and child nodes in Tkinter Treeview

Parent-Child Syntax with insert() 🔝

The main syntax is:

tree.insert(parent, index, iid=None, text='', values=(), open=False)

For a top-level item:

parent_id=tree.insert('', tk.END, text='Languages')

For a child:

tree.insert(parent_id, tk.END, text='Python')

The important difference is the first argument.

parentResult
''Creates a top-level item.
An existing iidCreates a child of that item.

Understanding Treeview iid 🔝

Every Treeview item has an identifier called an iid.

If you do not provide one, insert() creates an identifier and returns it.

parent_id=tree.insert('', tk.END, text='Languages')
print(parent_id)

You can also assign one yourself:

tree.insert('', tk.END, iid='languages', text='Languages')

and use the same ID when inserting children:

tree.insert('languages', tk.END, iid='python', text='Python')

iid, text and values Are Different

tree.insert(
    '',
    tk.END,
    iid='student_101',
    text='Student',
    values=(101, 'Alex')
)

Here:

student_101Internal Treeview item ID.
StudentText displayed in tree column #0.
101, AlexValues stored in the additional data columns.
More on Treeview insert() and iid

Basic Parent-Child Treeview Example 🔝

import tkinter as tk
from tkinter import ttk

root=tk.Tk()
root.geometry('420x300')
root.title('Treeview Parent Child - plus2net')

tree=ttk.Treeview(root, columns=('id', 'name'), show='tree headings')
tree.grid(row=0, column=0, padx=20, pady=20)

tree.heading('#0', text='Type')
tree.heading('id', text='ID')
tree.heading('name', text='Name')

tree.column('#0', width=120)
tree.column('id', width=60, anchor='center')
tree.column('name', width=140)

tree.insert('', tk.END, iid='p1', text='Parent', values=(1, 'Alex'), open=True)
tree.insert('p1', tk.END, iid='c1', text='Child', values=(2, 'Child Alex'))

root.mainloop()

The relationship is created here:

tree.insert('p1', tk.END, ...)

because p1 is the parent item's iid.

open=True and open=False 🔝

The open option controls whether an item's children are expanded or collapsed.

Expanded Parent

tree.insert('', tk.END, iid='p1', text='Parent', open=True)

The children of p1 are displayed.

Collapsed Parent

tree.insert('', tk.END, iid='p1', text='Parent', open=False)

The children still exist, but they remain hidden until the parent is expanded.

Example with Three Levels

tree.insert('', tk.END, iid='A', text='Level 1', open=True)
tree.insert('A', tk.END, iid='B', text='Level 2', open=False)
tree.insert('B', tk.END, iid='C', text='Level 3')

Level 2 is visible because Level 1 is open. Level 3 is hidden because Level 2 is closed.

show Option and Tree Column #0 🔝

showDisplay
'tree'Shows tree column #0 and hierarchy, without headings.
'headings'Shows headings and additional data columns, but hides #0.
'tree headings'Shows both tree hierarchy and headings.
''Hides both tree column and headings.

For a user-expandable parent-child interface, use:

tree['show']='tree headings'

or:

tree['show']='tree'

show='headings' hides the special #0 tree column and therefore hides the normal tree expand/collapse indicators.

Multiple Levels of Parent and Child Nodes 🔝

import tkinter as tk
from tkinter import ttk

root=tk.Tk()
root.geometry('430x300')
root.title('Treeview Hierarchy - plus2net')

style=ttk.Style()
style.configure('Treeview', rowheight=24)

tree=ttk.Treeview(root, columns=('id', 'name'), show='tree headings', selectmode='browse')
tree.grid(row=0, column=0, padx=20, pady=20)

tree.column('#0', width=120)
tree.column('id', width=60, anchor='center')
tree.column('name', width=140)

tree.heading('#0', text='Node')
tree.heading('id', text='ID')
tree.heading('name', text='Name')

tree.insert('', tk.END, iid='a', text='Root A', values=('a', 'Alex'))
tree.insert('', tk.END, iid='1', text='Parent 1', values=(1, 'Alex'), open=True)
tree.insert('1', tk.END, iid='1c', text='Child 1', values=('1c', 'Child Alex'))
tree.insert('', tk.END, iid='2', text='Parent 2', values=(2, 'Ron'), open=True)
tree.insert('2', tk.END, iid='2c', text='Child 2', values=('2c', 'Child Ron'), open=True)
tree.insert('2c', tk.END, iid='2cc', text='Grandchild', values=('2cc', 'Grandchild Ron'))

root.mainloop()

Find the Parent of an Item 🔝

Use parent().

parent_id=tree.parent('2cc')
print(parent_id)
Sample Output
2c

A top-level item has an empty parent:

print(tree.parent('2'))
Sample Output
''

Check whether an Item Is Top Level

if tree.parent(item_id)=='':
    print('Top-level item')

Get the Children of a Parent 🔝

Use:

children=tree.get_children('2')
print(children)

To get top-level items:

top_level=tree.get_children()

or explicitly:

top_level=tree.get_children('')

Read Values of Top-Level Items

names=[]

for item_id in tree.get_children():
    values=tree.item(item_id, 'values')
    names.append(values[1])

print(names)

Read All Parent and Child Nodes Recursively 🔝

Use a recursive function when the complete hierarchy is required.

def read_nodes(parent='', level=0):
    for item_id in tree.get_children(parent):
        text=tree.item(item_id, 'text')
        values=tree.item(item_id, 'values')
        print('  '*level, item_id, text, values)
        read_nodes(item_id, level+1)

read_nodes()

The function:

  1. reads the children of the current parent,
  2. processes each item,
  3. calls itself again using that item as the next parent.

This works for trees containing any practical number of nested levels.

Expand or Collapse Nodes Programmatically 🔝

Expand

tree.item('2', open=True)

Collapse

tree.item('2', open=False)

Read Current State

is_open=tree.item('2', 'open')
print(is_open)

Toggle Open and Closed State

def toggle_node(item_id):
    current=tree.item(item_id, 'open')
    tree.item(item_id, open=not current)

Open Parent and Show Child

tree.item('2', open=True)
tree.selection_set('2c')
tree.focus('2c')
tree.see('2c')

see() is especially useful because it makes an item visible and opens ancestors when required.

Move an Existing Item to Another Parent 🔝

Use move() to change an item's parent or position.

tree.move('1c', '2', tk.END)

The item 1c now becomes a child of 2.

Move an Item to the Top Level

tree.move('1c', '', tk.END)

The empty parent moves it back to the root level.

Insert User-Entered Data as Parent or Child 🔝

Insert user-entered parent and child items into Tkinter Treeview

The user can select an existing Treeview row and use its iid as the parent of a new item. Leaving the parent field blank creates a top-level item.

Insert User Input as Parent or Child Treeview Item

Improved User Input Example

import tkinter as tk
from tkinter import ttk

def selection_changed(event):
    selected=tree.selection()
    parent_var.set(selected[0] if selected else '')

def insert_item():
    parent_id=parent_var.get().strip()
    item_id=iid_var.get().strip()
    node_text=text_var.get().strip()
    value=value_var.get().strip()

    if parent_id and not tree.exists(parent_id):
        status_var.set('Parent iid does not exist')
        return

    if item_id and tree.exists(item_id):
        status_var.set('iid already exists')
        return

    if not node_text:
        status_var.set('Enter node text')
        return

    if item_id:
        new_id=tree.insert(parent_id, tk.END, iid=item_id, text=node_text, values=(value,))
    else:
        new_id=tree.insert(parent_id, tk.END, text=node_text, values=(value,))

    if parent_id:
        tree.item(parent_id, open=True)

    tree.selection_set(new_id)
    tree.focus(new_id)
    tree.see(new_id)

    iid_var.set('')
    text_var.set('')
    value_var.set('')
    status_var.set('Item inserted')

root=tk.Tk()
root.geometry('620x320')
root.title('Insert Parent Child Treeview - plus2net')

style=ttk.Style()
style.configure('Treeview', rowheight=24)

tree=ttk.Treeview(root, columns=('name',), show='tree headings', selectmode='browse')
tree.grid(row=0, column=0, rowspan=6, padx=10, pady=20)

tree.heading('#0', text='Node')
tree.heading('name', text='Name')
tree.column('#0', width=140)
tree.column('name', width=150)

tree.insert('', tk.END, iid='p1', text='Parent 1', values=('Alex',), open=True)
tree.insert('p1', tk.END, iid='c1', text='Child 1', values=('Child Alex',))

parent_var=tk.StringVar()
iid_var=tk.StringVar()
text_var=tk.StringVar()
value_var=tk.StringVar()
status_var=tk.StringVar()

tk.Label(root, text='Parent iid').grid(row=0, column=1, sticky='e')
tk.Entry(root, textvariable=parent_var).grid(row=0, column=2)

tk.Label(root, text='iid').grid(row=1, column=1, sticky='e')
tk.Entry(root, textvariable=iid_var).grid(row=1, column=2)

tk.Label(root, text='Tree text').grid(row=2, column=1, sticky='e')
tk.Entry(root, textvariable=text_var).grid(row=2, column=2)

tk.Label(root, text='Value').grid(row=3, column=1, sticky='e')
tk.Entry(root, textvariable=value_var).grid(row=3, column=2)

tk.Button(root, text='Insert', command=insert_item).grid(row=4, column=2, pady=10)
tk.Label(root, textvariable=status_var).grid(row=5, column=1, columnspan=2)

tree.bind('<<TreeviewSelect>>', selection_changed)

root.mainloop()

How the Parent Field Works

If the parent field is blank:

parent_id=''

the new item becomes a root item.

If it contains:

p1

the new item becomes a child of p1.

Why Validate parent and iid?

This check prevents an invalid parent:

if parent_id and not tree.exists(parent_id):
    return

This prevents duplicate item IDs:

if item_id and tree.exists(item_id):
    return

Common Parent-Child Treeview Mistakes 🔝

1. Thinking open=True Makes the Item Visible

open controls whether an item's children are expanded. The item itself depends on its parent's state.

2. Passing a Nonexistent Parent iid

This is invalid if parent_99 does not exist:

tree.insert('parent_99', tk.END, text='Child')

Check first:

if tree.exists(parent_id):
    tree.insert(parent_id, tk.END, text='Child')

3. Reusing an iid

Every Treeview item identifier must be unique.

4. Confusing iid with text

The identifier is used by Treeview internally, while text is displayed in column #0.

5. Using show='headings' for a Visible Hierarchy

This hides the tree column and its normal expand/collapse indicators. Use tree or tree headings when users need to navigate the hierarchy.

6. Assuming get_children() Returns the Whole Tree

Without a parent it returns only root items. Traverse recursively when all descendants are needed.

7. Using selection()[0] without a Check

A selection may be empty.

selected=tree.selection()

if selected:
    parent_id=selected[0]

8. Creating a One-Item Tuple without a Comma

This is a string:

values=('Alex')

This is a one-item tuple:

values=('Alex',)

9. Configuring ttk.Style with the Widget Instead of a Style Name

Avoid:

style.configure(tree, rowheight=20)

Use:

style.configure('Treeview', rowheight=20)

Treeview Parent-Child Summary 🔝

  • An empty parent '' creates a top-level item.
  • An existing item iid used as the parent creates a child.
  • iid uniquely identifies each Treeview item.
  • If no iid is supplied, insert() creates and returns one.
  • iid, text and values represent different parts of an item.
  • The tree label is displayed through column #0.
  • open=True expands an item's children.
  • open=False collapses an item's children.
  • An ancestor must be open for descendants to be visible.
  • item(iid, open=True) expands an existing item.
  • parent(iid) returns an item's parent.
  • get_children(iid) returns direct children.
  • get_children() returns top-level items only.
  • Use recursion to process every level of a hierarchy.
  • exists(iid) checks whether an item ID is valid.
  • move() can move an existing item to another parent.
  • see() helps bring nested items into view.
  • Use tree or tree headings when the hierarchy should be visible to users.
Learn next: Return to the main Treeview tutorial for selection, editing and scrollbars, or continue with Treeview insert() for more examples of adding rows and item IDs.
Treeview insert() JSON Treeview Viewer MySQL Records in Treeview




Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
©2000-2026   plus2net.com   All rights reserved worldwide Privacy Policy Disclaimer