The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Use ttk.Treeview to display rows and columns in a Tkinter app. It is a hierarchical widget rather than a dedicated spreadsheet table, but with show="headings" it presents a straightforward table layout. Sorting, filtering, and editing are application logic you add around the widget.
Create a basic Tkinter table
Import ttk, define the named columns, add headings, and insert row values in the same order as the columns tuple. The Python Software Foundation describes Treeview as a widget that “displays a hierarchical collection of items.” Its tree-label column is #0; show="headings" hides that column so the widget looks like a plain table.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
columns = ("name", "city", "score")
tree = ttk.Treeview(root, columns=columns, show="headings", height=8)
for name, width in (("name", 180), ("city", 140), ("score", 90)):
tree.heading(name, text=name.title())
tree.column(name, width=width)
for row in [("Ari", "London", 92), ("Bo", "Leeds", 85)]:
tree.insert("", "end", values=row)
tree.pack(fill="both", expand=True)
root.mainloop()
For each row, insert("", "end", values=...) adds a top-level item at the end. The values map positionally to the named columns. For hierarchical data, use a parent item ID in place of the empty parent string and insert children beneath it. Column identifiers such as score and displayed column positions such as #1 are different: use the name when addressing a named data column, and the displayed identifier when identifying a cell from a mouse event.
Add vertical and horizontal scrollbars
A scrollbar and Treeview need a paired connection: the scrollbar calls the widget’s view method, and the widget reports its scrolling position back to the scrollbar. This example puts both bars beside the table and lets the table expand with its frame.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
frame = ttk.Frame(root)
frame.pack(fill="both", expand=True)
frame.rowconfigure(0, weight=1)
frame.columnconfigure(0, weight=1)
tree = ttk.Treeview(frame, columns=columns, show="headings")
ys = ttk.Scrollbar(frame, orient="vertical", command=tree.yview)
xs = ttk.Scrollbar(frame, orient="horizontal", command=tree.xview)
tree.configure(yscrollcommand=ys.set, xscrollcommand=xs.set)
tree.grid(row=0, column=0, sticky="nsew")
ys.grid(row=0, column=1, sticky="ns")
xs.grid(row=1, column=0, sticky="ew")
Keep the two hookups matched: command=tree.yview goes with yscrollcommand=ys.set; for horizontal scrolling, pair tree.xview with xscrollcommand=xs.set.
Sort when a column heading is clicked
Treeview does not automatically sort rows. Attach a callback to each heading, retrieve the values, sort them, and move the existing items into the resulting order. Since values read from a Treeview are strings, convert numeric values before comparison.
Rank #2
def sort_by(tree, column, reverse=False, numeric=False):
items = [(tree.set(iid, column), iid) for iid in tree.get_children("")]
if numeric:
items.sort(key=lambda pair: float(pair[0]), reverse=reverse)
else:
items.sort(key=lambda pair: pair[0].casefold(), reverse=reverse)
for index, (_, iid) in enumerate(items):
tree.move(iid, "", index)
tree.heading(
column,
command=lambda: sort_by(tree, column, not reverse, numeric)
)
for column in columns:
tree.heading(
column,
command=lambda c=column: sort_by(
tree, c, numeric=(c == "score")
)
)
The default argument c=column captures the current column name for each callback. Use the numeric option only for columns containing values that can be parsed as numbers. Text sorting puts values such as 9,500 and 82,000 in lexicographic rather than numeric order; formatted numbers need a parser that removes or handles separators. Dates and locale-specific numbers likewise need parsing that matches their actual format.
Edit rows with a form
For a simple editor, let users select a row, load its values into input fields, validate the fields, and write the updated values back with tree.item. The form layout is application-specific; the central update operation looks like this:
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteselected = tree.selection()
if selected:
iid = selected[0]
updated_values = (name_entry.get(), city_entry.get(), score_entry.get())
# Validate required fields and value constraints before this line.
tree.item(iid, values=updated_values)
Bind a selection handler to <<TreeviewSelect>> to populate the entries when the selected item changes. Validate before updating—for example, ensure a required name is present and that a score has the permitted format or range.
Edit a cell in place
Treeview does not provide built-in spreadsheet-style in-cell editing in this approach. To create it, bind a double-click, identify the clicked row and display column, then position an Entry over the visible cell. Save the entry on Return or focus loss; Escape can cancel rather than commit.
def begin_cell_edit(event):
iid = tree.identify_row(event.y)
display_column = tree.identify_column(event.x)
if not iid or display_column == "#0":
return
box = tree.bbox(iid, display_column)
if not box:
return
x, y, width, height = box
# Create and place a ttk.Entry over (x, y, width, height).
# On save, update the matching value with tree.item(iid, values=...).
tree.bind("<Double-1>", begin_cell_edit)
identify_column returns a displayed column identifier, not necessarily the name used in the columns tuple. Map that identifier to the corresponding value position before updating the row. An empty result from bbox means there is no visible cell rectangle to edit, so do not place an overlay editor.
Search or filter rows
Filtering is also application logic. Keep the original rows in a Python collection, then rebuild the displayed items from rows that match the current query. This example searches case-insensitively for a substring in any field and refreshes whenever the search variable changes.
Free tools Windows power users keep installed
One-click scans. No signup required.
Best Value
rows = [
("Ari", "London", "92"),
("Bo", "Leeds", "85"),
]
query = tk.StringVar()
search = ttk.Entry(root, textvariable=query)
search.pack(fill="x")
def refresh(*_):
term = query.get().casefold()
tree.delete(*tree.get_children(""))
for row in rows:
if term in " ".join(row).casefold():
tree.insert("", "end", values=row)
query.trace_add("write", refresh)
refresh()
Change the match expression if the intended behavior is prefix or exact matching, or if only selected columns should be searched. For large datasets, avoid doing expensive work on every keystroke; the sources cited here do not establish a general dataset-size threshold.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Style the table and check the Tk version
Use ttk.Style for themed widget styling and Treeview tags for row-specific formatting. Ttk styling differs from classic Tk options such as fg and bg. Theme behavior can vary: Python Guides reports that the Windows vista theme ignores heading background colors and demonstrates switching to clam. Treat that as a theme-specific observation, and verify appearance on the operating system and theme your app will use.
Check the Tk runtime before depending on recent Treeview options. The official reference lists Treeview additions in Tk 9.0, including select type, striped rows, frozen title columns or items, and hidden items; Tk 9.1 adds row-height and heading-height options. These are not available in every Tk installation.
When Treeview is the right choice
Treeview is a standard-library choice for conventional tables with selectable rows and custom interactions. An Entry grid may suit a small table where users should edit every cell directly. A third-party grid such as tksheet may also be relevant when spreadsheet-like behavior is central, while ttkbootstrap documents a Tableview wrapper with sorting, searching, and pagination. Those alternatives are separate software packages, not part of Python’s standard library.
Python Guides reports running its examples with Python 3.12.5 and Tk 8.6.13 on Windows 11; that is the tutorial author’s stated environment, not an independent test of the examples here. Consult the Python tkinter.ttk reference for widget details, the Python Guides Treeview tutorial for end-to-end examples, and ttkbootstrap’s Treeview documentation for its wrapper options.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




