";require "../templates/head_jq_bs4.php";echo "";$img_path="..";require "top-link-tkinter.php";require "templates/top_bs4.php";echo "

Dynamic Tkinter Treeview Columns from Different Data Sources

";require "templates/body_start.php";?>CSV Excel Pandas MySQL and SQLite as data sources for Tkinter Treeview

A Tkinter Treeview can display data even when the number and names of columns are not known while writing the GUI. We can read the column names from CSV, Excel, Pandas, MySQL, SQLite or another source and create the Treeview columns dynamically.

The useful pattern is the same for every source:

headers=[...]rows=[...]configure_treeview(tree, headers, rows)

The data-reading code changes, but the Treeview-building code remains the same.

Sample Student Data: Excel, CSV, MySQL, SQLite and Pandas


Why Create Treeview Columns Dynamically? 🔝

A database query can return a different number of columns depending on the selected fields.

SELECT id, name FROM studentSELECT id, name, class FROM studentSELECT * FROM student

The first query returns two columns, the second returns three, and the third returns all columns in the table.

Instead of hard-coding five Treeview columns, Python can inspect the returned column names and build the interface automatically.

Dynamic creation of Tkinter Treeview columns and headings

Use the Same Data Structure for Every Source 🔝

Regardless of whether the source is CSV, Excel, Pandas or a database, convert the result into:

headers=['id', 'Name', 'Class', 'Mark', 'Gender']rows=[    (1, 'Alex', 'Four', 75, 'Male'),    (2, 'Ravi', 'Three', 65, 'Male')]

The Treeview function does not need to know where those two objects came from.

Create the Treeview 🔝

import tkinter as tkfrom tkinter import ttkroot=tk.Tk()root.geometry('700x350')root.title('Dynamic Treeview - plus2net')tree=ttk.Treeview(root, show='headings', selectmode='browse')tree.grid(row=0, column=0, sticky='nsew')

show='headings' is appropriate for flat tabular data because the special Treeview column #0 is not required.

selectmode='browse' means that one item can normally be selected at a time. It does not provide scrolling.

Tkinter Treeview Data from CSV and Excel with Dynamic Headers

Reusable Function to Build Dynamic Columns 🔝

The function below clears existing Treeview rows, creates safe internal column identifiers, adds the visible headings and inserts the supplied rows.

def configure_treeview(tree, headers, rows):    for item in tree.get_children():        tree.delete(item)    column_ids=[f'col{i}' for i in range(len(headers))]    tree['columns']=column_ids    tree['show']='headings'    for column_id, heading in zip(column_ids, headers):        heading_text='' if heading is None else str(heading)        tree.heading(column_id, text=heading_text)        tree.column(column_id, width=110, minwidth=60, anchor='center')    for row in rows:        values=list(row)        if len(values)<len(column_ids):            values+= ['']*(len(column_ids)-len(values))        tree.insert('', tk.END, values=values[:len(column_ids)])

Why Use col0, col1, col2?

A source can contain duplicate or blank headings:

ID | Name | Mark | Mark |

Using those values directly as Treeview column identifiers can create problems. Instead:

col0col1col2col3col4

are used internally, while the source headings remain the visible labels.

Why Not Use the First Field as iid?

The old pattern:

tree.insert('', tk.END, iid=row[0], values=row)

assumes that the first value is always unique and non-empty.

For a general-purpose dynamic-data tutorial, it is safer to omit iid and let Treeview generate its own item IDs.

MySQL Database as Data Source 🔝

Using SQLAlchemy, the result provides both column names and rows.

from sqlalchemy import create_engine, textengine=create_engine('mysql+mysqldb://userid:password@localhost/my_db')with engine.connect() as conn:    result=conn.execute(text('SELECT * FROM student'))    headers=list(result.keys())    rows=[tuple(row) for row in result]

Use your actual database credentials and the database driver configured for your project.

MySQL Database

Different SQL Queries, Different Treeview Columns

SELECT id, name FROM student

produces two Treeview columns, while:

SELECT id, name, class, mark FROM student

produces four. The rendering function does not change.

SQLite Database as Data Source 🔝

from sqlalchemy import create_engine, textengine=create_engine('sqlite:///my_db.db')with engine.connect() as conn:    result=conn.execute(text('SELECT * FROM student'))    headers=list(result.keys())    rows=[tuple(row) for row in result]
SQLite Database
Tkinter Treeview Data from Pandas, MySQL and SQLite

Pandas DataFrame as Data Source 🔝

import pandas as pddf=pd.read_excel('student.xlsx')headers=df.columns.tolist()rows=list(df.itertuples(index=False, name=None))

df.columns.tolist() creates the header list. itertuples() creates the row data without adding the DataFrame index.

Pandas DataFrame

Excel File with OpenPyXL 🔝

from openpyxl import load_workbookwb=load_workbook('student.xlsx', read_only=True, data_only=True)ws=wb.activerow_iter=ws.iter_rows(values_only=True)headers=next(row_iter)rows=list(row_iter)wb.close()

The first worksheet row becomes the headings and the remaining rows become Treeview data.

OpenPyXL Excel Tutorials Excel Data in Treeview

CSV File as Data Source 🔝

import csvwith open('student.csv', newline='', encoding='utf-8-sig') as file:    reader=csv.reader(file)    headers=next(reader)    rows=list(reader)

The with statement closes the CSV file automatically after reading.

Start with a Simple Python List 🔝

Before connecting a real data source, the dynamic logic can be tested with ordinary Python lists.

headers=['id', 'Name', 'Class', 'Mark', 'Gender']rows=[    [1, 'Alex', 'Four', 75, 'Male'],    [2, 'Ravi', 'Three', 65, 'Male']]configure_treeview(tree, headers, rows)

Reload Treeview when the Data Source Changes 🔝

The reusable function begins by deleting existing items:

for item in tree.get_children():    tree.delete(item)

It then assigns a new column list and inserts the new rows.

This means the same Treeview can first show:

id | name

and later be rebuilt as:

id | name | class | mark | gender

without creating another Treeview widget.

Dynamic Treeview Columns in Tkinter and Updating Data

Number of Visible Rows and Scrolling 🔝

The Treeview height option controls the approximate number of visible rows:

tree['height']=8

It does not limit how many items can be inserted.

For datasets containing more rows or columns, add scrollbars:

ys=ttk.Scrollbar(root, orient='vertical', command=tree.yview)xs=ttk.Scrollbar(root, orient='horizontal', command=tree.xview)tree.configure(yscrollcommand=ys.set, xscrollcommand=xs.set)

Complete Dynamic Treeview Example 🔝

This complete example uses a simple list as the data source. Replace the headers and rows section with any of the MySQL, SQLite, Pandas, Excel or CSV examples above.

import tkinter as tkfrom tkinter import ttkdef configure_treeview(tree, headers, rows):    for item in tree.get_children():        tree.delete(item)    column_ids=[f'col{i}' for i in range(len(headers))]    tree['columns']=column_ids    tree['show']='headings'    for column_id, heading in zip(column_ids, headers):        heading_text='' if heading is None else str(heading)        tree.heading(column_id, text=heading_text)        tree.column(column_id, width=110, minwidth=60, anchor='center')    for row in rows:        values=list(row)        if len(values)<len(column_ids):            values+=['']*(len(column_ids)-len(values))        tree.insert('', tk.END, values=values[:len(column_ids)])headers=['id', 'Name', 'Class', 'Mark', 'Gender']rows=[    (1, 'Alex', 'Four', 75, 'Male'),    (2, 'Ravi', 'Three', 65, 'Male'),    (3, 'Ron', 'Five', 80, 'Male')]root=tk.Tk()root.geometry('700x350')root.title('Dynamic Treeview - plus2net')root.rowconfigure(0, weight=1)root.columnconfigure(0, weight=1)tree=ttk.Treeview(root, show='headings', selectmode='browse', height=8)tree.grid(row=0, column=0, sticky='nsew', padx=(10, 0), pady=(10, 0))ys=ttk.Scrollbar(root, orient='vertical', command=tree.yview)ys.grid(row=0, column=1, sticky='ns', pady=(10, 0))xs=ttk.Scrollbar(root, orient='horizontal', command=tree.xview)xs.grid(row=1, column=0, sticky='ew', padx=(10, 0))tree.configure(yscrollcommand=ys.set, xscrollcommand=xs.set)configure_treeview(tree, headers, rows)root.mainloop()

Dynamic Treeview for Reports 🔝

The same technique is useful when the user changes a filter and a new database query returns another set of rows.

For example, a Combobox can select a month, a SQL query can retrieve matching records, and the existing Treeview can be cleared and filled with the new result.

Tkinter Monthly Report using Treeview, Combobox and MySQL

See the related monthly Treeview report tutorial for the complete project.

Common Dynamic Treeview Mistakes 🔝

1. Assuming the Number of Columns Is Fixed

Use the source metadata or first row to build the column list instead.

2. Using Source Headings Directly as Treeview IDs

Duplicate or blank headings can cause problems. Use internal identifiers such as col0, col1 and col2.

3. Using the First Data Value as iid

The first value may be duplicated or empty. Let Treeview generate item IDs unless the source contains a reliable unique key.

4. Forgetting to Clear Existing Rows

Before displaying a replacement dataset:

for item in tree.get_children():    tree.delete(item)

5. Assuming browse Means Scrollable

selectmode='browse' is a selection setting. Use Treeview scrollbars for scrolling.

6. Leaving Database Connections Open

Use a connection context manager:

with engine.connect() as conn:    ...

7. Leaving CSV Files Open

Use:

with open('student.csv') as file:    ...

8. Using Absolute Paths from One Computer

Avoid:

D:\student.xlsxE:\testing\sqlite\my_db.db

Use project-relative paths where possible.

9. Loading Huge Datasets into Memory

The examples use lists because the sample student data is small. For very large data sources, use pagination, SQL limits or incremental loading rather than placing every record in one Treeview.

See Treeview pagination with MySQL for one approach.

Dynamic Treeview Summary 🔝

Search DataFrame from TkinterMySQL Records in TreeviewMySQL Treeview PaginationQuery Window and Treeview

MySQL Records using Entry or LabelDelete MySQL RecordEdit and Update MySQL Product using Treeview