While building a Python application with a graphical user interface, I often need to display data clean and organized. The tables are perfect for this. However, when I started with Tkinter, I wasn’t sure how to create tables. After some research and experimentation, I discovered that the Treeview widget is the best option for displaying tabular data in Tkinter. In this tutorial, I will explain how to create tables in Python Tkinter with examples.
Create Tables in Python Tkinter
Let us learn how to create tables in Python Tkinter with different functionalities.
Read How to Create Python Tkinter Text Editor?
1. Create Table
We create a Tkinter table with the help of Treeview. It refers to hierarchical representation. The Tkinter.ttk module is used to drive a tree view and we use the tree view to make a table
import tkinter as tk
from tkinter import ttk
app = tk.Tk()
app.title("Customer Data")
# Create a Treeview widget
table = ttk.Treeview(app)
# Define the columns
table['columns'] = ('Name', 'Email', 'Phone')
# Format the columns
table.column('#0', width=0, stretch=tk.NO)
table.column('Name', anchor=tk.W, width=150)
table.column('Email', anchor=tk.W, width=200)
table.column('Phone', anchor=tk.W, width=150)
# Create the headings
table.heading('#0', text='', anchor=tk.W)
table.heading('Name', text='Name', anchor=tk.W)
table.heading('Email', text='Email', anchor=tk.W)
table.heading('Phone', text='Phone', anchor=tk.W)
# Sample data
data = [
('John Smith', 'john@example.com', '(555) 123-4567'),
('Emily Johnson', 'emily@example.com', '(555) 987-6543'),
('Michael Davis', 'michael@example.com', '(555) 246-8135')
]
# Configure alternating row colors
table.tag_configure('oddrow', background='#E8E8E8')
table.tag_configure('evenrow', background='#FFFFFF')
# Add data with alternating row colors
for i in range(len(data)):
if i % 2 == 0:
table.insert(parent='', index=i, values=data[i], tags=('evenrow',))
else:
table.insert(parent='', index=i, values=data[i], tags=('oddrow',))
# Pack the table
table.pack(expand=True, fill=tk.BOTH)
app.mainloop()You can look at the output in the screenshot below.

Check out How to Create Animations in Python with Tkinter?
2. Table with Scrollbar
When screen size is not enough to display the entire data. So to navigate around the data scrollbars are used. There are two types of scrollbars: Horizontal and Vertical Scrollbars.
# Create vertical scrollbar
vsb = ttk.Scrollbar(app, orient="vertical", command=table.yview)
vsb.pack(side='right', fill='y')
table.configure(yscrollcommand=vsb.set)
# Create horizontal scrollbar
hsb = ttk.Scrollbar(app, orient="horizontal", command=table.xview)
hsb.pack(side='bottom', fill='x')
table.configure(xscrollcommand=hsb.set)You can look at the output in the screenshot below.

Read How to Master Python Tkinter Events?
3. Table Input
We use the entry box for taking the input. When we enter the data as input in the entry box, the data will show in the table.
from tkinter import *
from tkinter import ttk
ws=Tk()
ws.title('PythonGuides')
ws.geometry('500x500')
set = ttk.Treeview(ws)
set.pack()
set['columns']= ('id', 'full_Name','award')
set.column("#0", width=0, stretch=NO)
set.column("id",anchor=CENTER, width=80)
set.column("full_Name",anchor=CENTER, width=80)
set.column("award",anchor=CENTER, width=80)
set.heading("#0",text="",anchor=CENTER)
set.heading("id",text="ID",anchor=CENTER)
set.heading("full_Name",text="Full_Name",anchor=CENTER)
set.heading("award",text="Award",anchor=CENTER)
#data
data = [
[1,"Jack","gold"],
[2,"Tom","Bronze"]
]
global count
count=0
for record in data:
set.insert(parent='',index='end',iid = count,text='',values=(record[0],record[1],record[2]))
count += 1
Input_frame = Frame(ws)
Input_frame.pack()
id = Label(Input_frame,text="ID")
id.grid(row=0,column=0)
full_Name= Label(Input_frame,text="Full_Name")
full_Name.grid(row=0,column=1)
award = Label(Input_frame,text="Award")
award.grid(row=0,column=2)
id_entry = Entry(Input_frame)
id_entry.grid(row=1,column=0)
fullname_entry = Entry(Input_frame)
fullname_entry.grid(row=1,column=1)
award_entry = Entry(Input_frame)
award_entry.grid(row=1,column=2)
def input_record():
global count
set.insert(parent='',index='end',iid = count,text='',values=(id_entry.get(),fullname_entry.get(),award_entry.get()))
count += 1
id_entry.delete(0,END)
fullname_entry.delete(0,END)
award_entry.delete(0,END)
#button
Input_button = Button(ws,text = "Input Record",command= input_record)
Input_button.pack()
ws.mainloop()You can look at the output in the screenshot below.

Read How to Create Tabbed Interfaces in Python with Tkinter Notebook Widget?
4. Table List
We create the list by using Treeview, in which we insert data to make a list. The Parent is the item, or empty string to create the top-level item. The index is an integer or value end.
from tkinter import *
from tkinter import ttk
ws = Tk()
ws.title('PythonGuides')
ws.geometry('500x500')
list = ttk.Treeview(ws)
list.pack()
list['columns']= ('Name','Gender','Title')
list.column("#0", width=0, stretch=NO)
list.column("Name",anchor=CENTER, width=80)
list.column("Gender",anchor=CENTER, width=80)
list.column("Title",anchor=CENTER, width=80)
list.heading("#0",text="",anchor=CENTER)
list.heading("Name",text="P_Name",anchor=CENTER)
list.heading("Gender",text="P_Gender",anchor=CENTER)
list.heading("Title",text="P_Title",anchor=CENTER)
list.insert(parent='',index='end',iid=0,text='',
values=('Todd S Core','Male','Mr'))
list.insert(parent='',index='end',iid=1,text='',
values=('Thomas C Wood','Male','Mr'))
list.insert(parent='',index='end',iid=2,text='',
values=('Misha J McKinney','Female','Mrs'))
list.insert(parent='',index='end',iid=3,text='',
values=('Teresa B Haight','Female','Ms'))
list.insert(parent='',index='end',iid=4,text='',
values=('Michael L McLaurin','Male','Mr'))
list.insert(parent='',index='end',iid=5,text='',
values=('David S Ward','Male','Mr'))
list.insert(parent='',index='end',iid=6,text='',
values=('Carolyn G Price','Feale','Mrs'))
list.insert(parent='',index='end',iid=7,text='',
values=('Diana D Lai','Female','Ms'))
list.insert(parent='',index='end',iid=8,text='',
values=('Bonnie E Duran','Female','Ms'))
list.insert(parent='',index='end',iid=9,text='',
values=('Joseph M Munger','Male','Mr'))
ws.mainloop()You can look at the output in the screenshot below.

Read How to Create an On/Off Toggle Switch in Python Tkinter?
5. Table Refresh
The Refresh function is meant to be used when we update anything inside our table data. And that updated data will be visible in the table once the table is refreshed.
from tkinter import *
from tkinter import ttk
ws = Tk()
ws.title('PythonGuides')
ws.geometry('500x500')
game_frame = Frame(ws)
game_frame.pack()
#scrollbar
game_scroll = Scrollbar(game_frame)
game_scroll.pack(side=RIGHT, fill=Y)
game_scroll = Scrollbar(game_frame,orient='horizontal')
game_scroll.pack(side= BOTTOM,fill=X)
my_game = ttk.Treeview(game_frame,yscrollcommand=game_scroll.set, xscrollcommand =game_scroll.set)
my_game.pack()
game_scroll.config(command=my_game.yview)
game_scroll.config(command=my_game.xview)
my_game['columns'] = ('player_id', 'player_name', 'player_Rank')
# format our column
my_game.column("#0", width=0, stretch=NO)
my_game.column("player_id",anchor=CENTER, width=80)
my_game.column("player_name",anchor=CENTER,width=80)
my_game.column("player_Rank",anchor=CENTER,width=80)
#Create Headings
my_game.heading("#0",text="",anchor=CENTER)
my_game.heading("player_id",text="Id",anchor=CENTER)
my_game.heading("player_name",text="Name",anchor=CENTER)
my_game.heading("player_Rank",text="Rank",anchor=CENTER)
#add data
my_game.insert(parent='',index='end',iid=0,text='',
values=('1','Ninja','101'))
my_game.insert(parent='',index='end',iid=1,text='',
values=('2','Ranger','102'))
my_game.insert(parent='',index='end',iid=2,text='',
values=('3','Deamon','103'))
my_game.insert(parent='',index='end',iid=3,text='',
values=('4','Dragon','104'))
my_game.insert(parent='',index='end',iid=4,text='',
values=('5','CrissCross','105'))
my_game.insert(parent='',index='end',iid=5,text='',
values=('6','ZaqueriBlack','106'))
my_game.insert(parent='',index='end',iid=6,text='',
values=('7','RayRizzo','107'))
my_game.insert(parent='',index='end',iid=7,text='',
values=('8','Byun','108'))
my_game.insert(parent='',index='end',iid=8,text='',
values=('9','Trink','109'))
my_game.insert(parent='',index='end',iid=9,text='',
values=('10','Twitch','110'))
my_game.insert(parent='',index='end',iid=10,text='',
values=('11','Animus','111'))
my_game.pack()
frame = Frame(ws)
frame.pack(pady=20)
#labels
playerid= Label(frame,text = "player_id")
playerid.grid(row=0,column=0 )
playername = Label(frame,text="player_name")
playername.grid(row=0,column=1)
playerrank = Label(frame,text="Player_rank")
playerrank.grid(row=0,column=2)
#Entry boxes
playerid_entry= Entry(frame)
playerid_entry.grid(row= 1, column=0)
playername_entry = Entry(frame)
playername_entry.grid(row=1,column=1)
playerrank_entry = Entry(frame)
playerrank_entry.grid(row=1,column=2)
#Select Record
def select_record():
#clear entry boxes
playerid_entry.delete(0,END)
playername_entry.delete(0,END)
playerrank_entry.delete(0,END)
#grab record
selected=my_game.focus()
#grab record values
values = my_game.item(selected,'values')
#temp_label.config(text=selected)
#output to entry boxes
playerid_entry.insert(0,values[0])
playername_entry.insert(0,values[1])
playerrank_entry.insert(0,values[2])
#save Record
def update_record():
selected=my_game.focus()
#save new data
my_game.item(selected,text="",values=(playerid_entry.get(),playername_entry.get(),playerrank_entry.get()))
#clear entry boxes
playerid_entry.delete(0,END)
playername_entry.delete(0,END)
playerrank_entry.delete(0,END)
#Buttons
select_button = Button(ws,text="Select Record", command=select_record)
select_button.pack(pady =10)
refresh_button = Button(ws,text="Refresh Record",command=update_record)
refresh_button.pack(pady = 10)
temp_label =Label(ws,text="")
temp_label.pack()
ws.mainloop()You can look at the output in the screenshot below.

By selecting a record and clicking on the Refresh button the records will be updated.
Check out How to Validate User Input in Python Tkinter?
6. Table Canvas
The canvas is used for drawing pictures, graphics text, or frames, we have created a table of 3 rows and each row contains 3 squares.
from tkinter import *
list = [[0,0,0,0], [0, 0, 0, 0], [0, 0, 0, 0]]
a = len(list)
length = 300//a
ws = Tk()
ws.geometry("500x500")
canvas = Canvas(ws, width=500, height=500, bg="#7698A6")
canvas.pack(side=RIGHT)
for i in range(a):
y = i * length
for j in range(a):
x = j * length
canvas.create_rectangle(x, y, x+length, y+length, fill="#D97E4A")
f = Frame(ws, width=200, height=500, bg="#F23E2E")
f.pack(side=RIGHT)
ws.mainloop()You can look at the output in the screenshot below.

We will get an output with a canvas having a table with 3 rows and 3 columns. It also has a grid view inside a table that helps to separate rows and columns.
Read How to Create a Search Box with Autocomplete in Python Tkinter?
7. Table Sort
Sort is a function that is used to rearrange the values in the form of ascending or descending order. But here, we are talking about sorting table data and we will be explaining how column sorting works in the Tkinter table.
import tkinter as tk
from tkinter import Tk, ttk
def down(event):
global cols_from, dx, cols_from_id
db= event.widget
if db.identify_region(event.x, event.y) != 'separator':
cols = db.identify_column(event.x)
cols_from_id =db.column(cols, 'id')
cols_from = int(cols[1:]) - 1
bbox = db.bbox(db.get_children("")[0], cols_from_id)
dx = bbox[0] - event.x
db.heading(cols_from_id, text='')
visual_drag.configure(displaycolumns=[cols_from_id])
visual_drag.place(in_=db, x=bbox[0], y=0, anchor='nw', width=bbox[2], relheight=1)
else:
cols_from = None
def BUP(event):
db = event.widget
cols_to = int(db.identify_column(event.x)[1:]) - 1
visual_drag.place_forget()
if cols_from is not None:
db.heading(cols_from_id, text=visual_drag.heading('#1', 'text'))
if cols_from != cols_to:
Tcols = list(db["displaycolumns"])
if Tcols[0] == "#all":
Tcols = list(db["columns"])
if cols_from > cols_to:
Tcols.insert(cols_to, Tcols[col_from])
Tcols.pop(cols_from + 1)
else:
Tcols.insert(cols_to + 1, Tcols[cols_from])
Tcols.pop(cols_from)
db.config(displaycolumns=Tcols)
def BMotion(event):
if visual_drag.winfo_ismapped():
visual_drag.place_configure(x=dx + event.x)
col_from = 0
ws= Tk()
columns = ["D", "C", "B", "A"]
sort = ttk.Treeview(ws, columns=columns, show='headings')
visual_drag = ttk.Treeview(ws, columns=columns, show='headings')
for cols in columns:
sort.heading(cols, text=cols)
visual_drag.heading(cols, text=cols)
for i in range(10):
sort.insert('', 'end', iid='line%i' % i,
values=(i+50, i+40, i+30, i+20, i+10))
visual_drag.insert('', 'end', iid='line%i' % i,
values=(i+50, i+40, i+30, i+20, i+10))
sort.grid()
sort.bind("<ButtonPress>", down)
sort.bind("<ButtonRelease>",BUP)
sort.bind("<Motion>",BMotion)
ws.mainloop()You can look at the output in the screenshot below.

We came up with the output where we can see that the columns are not arranged in order. As column C values should come after column D. So, here we just drag the column through mouse hover and re-arrange the following in ascending order.
Check out How to Create Message Boxes with Python Tkinter?
Conclusion
In this tutorial, I have explained how to create tables in Python Tkinter. I discussed some functionalities of tables like creating table, table with scrollbars, table input, table list, table refresh, table canvas, and table sort.
You may like to read:
- How to Save Text to a File Using Python Tkinter?
- How to Cancel Scheduled Functions with after_cancel() in Python Tkinter?
- How to Create GUI Layouts with Python Tkinter Separator?

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.