Sorting Tkinter Treeview columns in ascending or descending order using Pandas DataFrame Part I
my_disp()
Using the DataFrame df, this function creates column names l1 and creates a list of rows as r_set.
global df
l1=list(df) # List of column names as headers
r_set=df.to_numpy().tolist() # Create list of list using rows
Then the Treeview is added and on click of header the function my_sort(i) is called, here the name of the column i is passed as parameter.
All rows of DataFrame is inserted to Treeview by looping.
def my_disp():
global df
l1=list(df) # List of column names as headers
r_set=df.to_numpy().tolist() # Create list of list using rows
trv = ttk.Treeview(my_w, selectmode ='browse',
show='headings',height=5,columns=l1)
trv.grid(row=1,column=1,padx=30,pady=20)
for col in l1:
trv.column(col, width = 100, anchor ='c')
trv.heading(col, text =col,command=lambda col=col :my_sort(col))
## Adding data to treeview
for dt in r_set:
v=[r for r in dt] # creating a list from each row
trv.insert("",'end',iid=v[0],values=v) # adding row
my_sort(col)
This function receives the ( user clicked ) column name as parameter. To set the option ascending we will use the global variable order. Each time this function is called the value of the Boolean variable order is changed to True or False. This is done to toggle the sorting order from ascending to descending and vice versa
The dataframe is sorted by using the sort_values() method and the new DataFrame df is used to crate the Fresh view by calling my_disp().
def my_sort(col):
global df,order
if order:
order=False # set ascending value
else:
order=True
df=df.sort_values(by=[col],ascending=order)
my_disp() # refresh the Treeview
from tkinter import ttk
import tkinter as tk
# Creating tkinter my_w
my_w = tk.Tk()
my_w.geometry("560x280")
my_w.title("www.plus2net.com")
# Using Pandas DataFrame as data source
import pandas as pd # Pandas library
df = pd.read_excel('D:\student.xlsx') # create dataframe
order=True # To set the sorting to ascending or descending
def my_disp():
global df
l1=list(df) # List of column names as headers
r_set=df.to_numpy().tolist() # Create list of list using rows
trv = ttk.Treeview(my_w, selectmode ='browse',
show='headings',height=10,columns=l1)
trv.grid(row=1,column=1,padx=30,pady=20)
for col in l1:
trv.column(col, width = 100, anchor ='c')
trv.heading(col, text =col,command=lambda col=col :my_sort(col))
## Adding data to treeview
for dt in r_set:
v=[r for r in dt] # creating a list from each row
trv.insert("",'end',iid=v[0],values=v) # adding row
def my_sort(col):
global df,order
if order:
order=False # set ascending value
else:
order=True
df=df.sort_values(by=[col],ascending=order)
my_disp() # refresh the Treeview
my_disp()
my_w.mainloop()
Browse and select file
We can give option to user to browse local system and select Excel ( or CSV : Comma Separated Values ) file for creating the DataFrame. Here we have used Filedialog to create the dialog box for user to select file.
def browse_file(): # user selection of file to create dataframe
global df # access the dataframe
file = filedialog.askopenfilename() # show file dialog
if file: # user selected one file
df = pd.read_excel(file) # create dataframe
l1_path.config(text=file) # display the selected file path
my_disp()
else: # user cancel the file browser window
l1_path.config(text='No file is selected')
One buttonb1 is provided to trigger the function browse_file() and select the file. Labell1_path is used to display the path with file name the user has selected for creating the DataFrame. To display the path on the Label l1_path we used config().
from tkinter import ttk
import tkinter as tk
from tkinter import filedialog
my_w = tk.Tk()
my_w.geometry("560x280")
my_w.title("www.plus2net.com")
import pandas as pd # Pandas library
#df = pd.read_excel('D:\student.xlsx') # create dataframe
order=True # To set the sorting to ascending or descending
df = pd.DataFrame() # empty DataFrame object
b1 = tk.Button(my_w, text='Select File', bg='lightgreen',
width=20,command = lambda:browse_file())
b1.grid(row=1,column=1,padx=30,pady=5)
l1_path=tk.Label(my_w,text='',bg='yellow')
l1_path.grid(row=1,column=2,columnspan=2)
def browse_file(): # user selection of file to create dataframe
global df # access the dataframe
file = filedialog.askopenfilename() # show file dialog
if file: # user selected one file
df = pd.read_excel(file) # create dataframe
l1_path.config(text=file) # display the selected file path
my_disp()
else: # user cancel the file browser window
l1_path.config(text='No file is selected')
def my_disp(): # display the Treeview with data
global df
l1=list(df) # List of column names as headers
r_set=df.to_numpy().tolist() # Create list of list using rows
trv = ttk.Treeview(my_w, selectmode ='browse',
show='headings',height=10,columns=l1)
trv.grid(row=2,column=1,columnspan=3,padx=15,pady=10)
for col in l1:
trv.column(col, width = 100, anchor ='w')
trv.heading(col, text =col,command=lambda col=col :my_sort(col))
## Adding data to treeview
for dt in r_set:
v=[r for r in dt] # creating a list from each row
trv.insert("",'end',iid=v[0],values=v) # adding row
def my_sort(col): # Update the dataframe after sorting
global df,order
if order:
order=False # set ascending value
else:
order=True
df=df.sort_values(by=[col],ascending=order)
my_disp() # refresh the Treeview
my_w.mainloop()
Adding Vertical Scrollbar and showing DataFrame details
We can add one Label l1_dtl to show the number of rows and columns of the DataFrame df by using shape. Here to display the details we will be using config() to update the text option of the Label.
Vertical Scrollbar can be added while displaying the rows in Treeview. This code to be included inside my_disp() to show the Scrollbar
def my_disp(): # display the Treeview with data
global df
l1=list(df) # List of column names as headers
r_set=df.to_numpy().tolist() # Create list of list using rows
trv = ttk.Treeview(my_w, selectmode ='browse',
show='headings',height=10,columns=l1)
trv.grid(row=2,column=1,columnspan=4,padx=15,pady=10)
for col in l1:
trv.column(col, width = 100, anchor ='w')
trv.heading(col, text =col,command=lambda col=col :my_sort(col))
## Adding data to treeview
for dt in r_set:
v=[r for r in dt] # creating a list from each row
trv.insert("",'end',iid=v[0],values=v) # adding row
l1_dlt.config(text= "Rows:"+str(df.shape[0])+" Cols:"+str(df.shape[1]))
vs = ttk.Scrollbar(my_w,orient="vertical", command=trv.yview)#V Scrollbar
trv.configure(yscrollcommand=vs.set) # connect to Treeview
vs.grid(row=2,column=5,sticky='ns')
from tkinter import ttk
import tkinter as tk
from tkinter import filedialog
my_w = tk.Tk()
my_w.geometry("560x310")
my_w.title("www.plus2net.com")
import pandas as pd # Pandas library
#df = pd.read_excel('D:\student.xlsx') # create dataframe
order=True # To set the sorting to ascending or descending
df = pd.DataFrame() # empty DataFrame object
b1 = tk.Button(my_w, text='Select File', bg='lightgreen',
width=20,command = lambda:browse_file())
b1.grid(row=1,column=1,padx=30,pady=5)
l1_dlt=tk.Label(my_w,text='',bg='lightgreen')
l1_dlt.grid(row=1,column=2)
l1_path=tk.Label(my_w,text='',bg='yellow')
l1_path.grid(row=1,column=3,columnspan=2)
def browse_file(): # user selection of file to create dataframe
global df # access the dataframe
file = filedialog.askopenfilename() # show file dialog
if file: # user selected one file
df = pd.read_excel(file) # create dataframe
l1_path.config(text=file) # display the selected file path
my_disp()
else: # user cancel the file browser window
l1_path.config(text='No file is selected')
def my_disp(): # display the Treeview with data
global df
l1=list(df) # List of column names as headers
r_set=df.to_numpy().tolist() # Create list of list using rows
trv = ttk.Treeview(my_w, selectmode ='browse',
show='headings',height=10,columns=l1)
trv.grid(row=2,column=1,columnspan=4,padx=15,pady=10)
for col in l1:
trv.column(col, width = 100, anchor ='w')
trv.heading(col, text =col,command=lambda col=col :my_sort(col))
## Adding data to treeview
for dt in r_set:
v=[r for r in dt] # creating a list from each row
trv.insert("",'end',iid=v[0],values=v) # adding row
l1_dlt.config(text= "Rows:"+str(df.shape[0])+" Cols:"+str(df.shape[1]))
vs = ttk.Scrollbar(my_w,orient="vertical", command=trv.yview)#V Scrollbar
trv.configure(yscrollcommand=vs.set) # connect to Treeview
vs.grid(row=2,column=5,sticky='ns')
def my_sort(col): # Update the dataframe after sorting
global df,order
if order:
order=False # set ascending value
else:
order=True
df=df.sort_values(by=[col],ascending=order)
my_disp() # refresh the Treeview
my_w.mainloop()