Sorting Tkinter Treeview Columns using Pandas DataFrame

Sorting Tkinter Treeview columns using a Pandas DataFrame

This project displays a Pandas DataFrame in a Tkinter Treeview and lets the user sort any column by clicking its heading.

Pandas sort_values() performs the actual sorting. Clicking the same heading again reverses the order from ascending to descending or from descending to ascending.

The application can load either an Excel file using read_excel() or a CSV file using read_csv().

Excel / CSV
     |
     v
Pandas DataFrame
     |
     v
Tkinter Treeview
     |
     v
Click column heading
     |
     v
df.sort_values()
     |
     v
Refresh Treeview rows

Load Excel or CSV Data Top ↑

The older example used a fixed local path:

df=pd.read_excel('D:\\student.xlsx')

A Tkinter file dialog makes the project more reusable because the user can select the data file while the program is running.

file_path=filedialog.askopenfilename(
    title='Select Excel or CSV file',
    filetypes=[
        ('Excel files','*.xlsx *.xls'),
        ('CSV files','*.csv'),
        ('All files','*.*')
    ]
)

The file extension decides which Pandas reader is used.

extension=os.path.splitext(
    file_path
)[1].lower()

if extension=='.csv':
    df=pd.read_csv(file_path)
else:
    df=pd.read_excel(file_path)

Create the Treeview Only Once Top ↑

The earlier my_disp() function created another Treeview every time the data was sorted.

The revised application creates one Treeview when the GUI starts:

tree=ttk.Treeview(
    table_frame,
    show='headings',
    selectmode='browse'
)

Sorting then changes only the rows and heading labels. The widget itself is reused.

Create Treeview once
        |
        v
Load DataFrame
        |
        v
Insert rows
        |
        v
Sort DataFrame
        |
        v
Delete old rows
        |
        v
Insert sorted rows

Create Dynamic Treeview Columns Top ↑

Different Excel and CSV files can contain different headings, so the columns are created dynamically.

Instead of using DataFrame column names as Treeview's internal IDs, we create predictable IDs such as:

c0
c1
c2
c3

The original DataFrame names are still displayed as the headings.

column_ids=[
    f'c{i}'
    for i in range(
        len(df.columns)
    )
]

tree['columns']=column_ids

Each heading calls the sorting function with the corresponding DataFrame column name.

tree.heading(
    column_id,
    text=str(column_name),
    command=lambda name=column_name:
        sort_column(name)
)

Sort a DataFrame Column with sort_values() Top ↑

Pandas sort_values() sorts the complete DataFrame using the selected column.

sorted_df=df.sort_values(
    by=column_name,
    ascending=ascending,
    na_position='last',
    kind='stable'
)

The options used here are:

  • by=column_name chooses the clicked column.
  • ascending=True sorts from lower to higher values.
  • ascending=False reverses the order.
  • na_position='last' keeps missing values at the bottom.
  • kind='stable' preserves the relative order of equal values when sorting one column.

Toggle Ascending and Descending for Each Column Top ↑

The old program used one global Boolean variable:

order=True

This meant clicking one column changed the next sort direction for every other column.

The revised application stores a separate next-sort direction for each heading:

sort_state={}

When a heading is clicked:

ascending=sort_state.get(
    column_name,
    True
)

sort_state[column_name]=not ascending

Therefore each column starts with ascending order independently.

After sorting, the clicked heading also shows the current direction:

Name (ASC)

or:

Name (DESC)

Refresh Treeview Rows after Sorting Top ↑

First delete the currently displayed Treeview items:

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

Then insert the rows from the newly sorted DataFrame.

for row in df.itertuples(
    index=False,
    name=None
):
    values=[
        '' if pd.isna(value)
        else value
        for value in row
    ]

    tree.insert(
        '',
        tk.END,
        values=values
    )

The first cell is no longer used as the Treeview iid. This avoids duplicate-ID errors when several rows contain the same first-column value.

Add Vertical and Horizontal Scrollbars Top ↑

Tkinter Treeview column sorting with scrollbars and DataFrame details

A vertical scrollbar is useful for many rows, while a horizontal scrollbar helps when the selected file contains many columns.

y_scroll=ttk.Scrollbar(
    table_frame,
    orient='vertical',
    command=tree.yview
)

x_scroll=ttk.Scrollbar(
    table_frame,
    orient='horizontal',
    command=tree.xview
)

tree.configure(
    yscrollcommand=y_scroll.set,
    xscrollcommand=x_scroll.set
)

The number of rows and columns is displayed using:

details_var.set(
    f'Rows: {df.shape[0]}   Columns: {df.shape[1]}'
)

Browse and Select another File Top ↑

Tkinter file browser selecting Excel data for Treeview sorting

The Select File Button can be used repeatedly. When another file is selected:

  • the old DataFrame is replaced;
  • old Treeview rows are removed;
  • new dynamic columns are created;
  • the sort-state dictionary is reset;
  • the new data is displayed.

Complete Tkinter Pandas Sorting Application Top ↑

Video: Sort Treeview Columns with Pandas Top ↑

Sorting Tkinter Treeview Columns in Ascending or Descending Order using Pandas DataFrame

How the Sort Direction Works Top ↑

Assume the user clicks the Mark heading for the first time.

sort_state.get(
    'Mark',
    True
)

No previous value exists, so the default is True.

The DataFrame is therefore sorted in ascending order:

35
42
56
78
91

The next state is stored as:

sort_state['Mark']=False

Clicking Mark again produces:

91
78
56
42
35

If the user then clicks another column such as Name, that column independently starts with ascending order.

Why the DataFrame Index Is Reset Top ↑

sort_values() changes row order but normally keeps the existing DataFrame index labels.

After sorting we use:

df=sorted_df.reset_index(
    drop=True
)

This gives the sorted DataFrame a clean sequential index. The index is not displayed in Treeview.

Sorting Missing Values Top ↑

DataFrames may contain missing values. The sorting operation uses:

na_position='last'

so missing values remain at the bottom for both ascending and descending views.

When the DataFrame is displayed, a missing value is converted to an empty Treeview cell:

'' if pd.isna(value)
else value

Continue the Pandas Treeview Project Top ↑

Column sorting is one part of a larger DataFrame viewer. You can continue by adding search controls:

Search DataFrame and Display Results in Treeview

You can also let the user choose which DataFrame columns should be visible:

Select DataFrame Columns using Checkbuttons

For SQLite data, continue with the database version:

SQLite DataFrame with Treeview Sorting and CSV Export

The same column-sorting pattern is also used in the directory browser project:

Directory Browser with Treeview Column Sorting

Frequently Asked Questions Top ↑

Q1: How are Treeview columns sorted?

Clicking a Treeview heading calls a function that uses Pandas sort_values() on the corresponding DataFrame column and then refreshes the displayed rows.

Q2: How does clicking the same heading reverse the order?

A dictionary stores the next ascending or descending state for each DataFrame column independently.

Q3: Why is the Treeview created only once?

Reusing one widget avoids creating overlapping Treeviews and scrollbars whenever the user sorts the data.

Q4: Can the application sort both Excel and CSV files?

Yes. Excel files are read with read_excel() and CSV files with read_csv(). Both become Pandas DataFrames before being displayed.

Q5: Why is the first DataFrame column not used as the Treeview iid?

Values in the first column may repeat. Letting Treeview create its own internal item identifiers prevents duplicate iid errors.

Q6: What happens to missing values during sorting?

The example uses na_position='last' so missing values appear after the non-missing values and are displayed as blank Treeview cells.

Q7: Can sorting be combined with DataFrame searching?

Yes. A filtered DataFrame can be displayed with the same Treeview refresh method and then sorted using the selected column.


SQLite to CSV DataFrame Search Select Columns SQLite Sorting

Tkinter Projects Tkinter Pandas Projects


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