Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Use ttk.Treeview to display a table in Tkinter. Set show="headings" for a plain rows-and-columns appearance, then add scrollbars and implement sorting, editing, or filtering in your application code as needed.

Does Tkinter have a table widget?

Tkinter’s standard themed widget for this job is ttk.Treeview. Python’s official documentation describes it as a widget that displays “a hierarchical collection of items.” It can show parent-and-child items, but configured with headings it works well as a conventional table with selectable rows. It is not a spreadsheet or a database table.

Here is a minimal table with three columns and two rows:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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()

The columns tuple defines the data-column identifiers, and each inserted row’s values must follow that order. show="headings" hides Treeview’s special tree-label column, called #0, so only the named columns appear. The height value sets the number of visible rows, not a maximum number of stored records.

#1 Best Overall
WoneNice USB Laser Barcode Scanner Wired Handheld Bar Code Scanner Reader Black
  • Plug and play, This laser handheld barcode scanner has simple installation with any USB port and Ideal for businesses, shops and warehouse operations. Its function is unbeatable and easy to use, design is stylish
  • Compatible with Windows, Mac, and Linux; works with Word, Excel, Novell, and all common software
  • Scanning Speed: 200 scans per second. Scanning angle: Inclination angle 55°, Elevation angle 65°. Operational Light Source:Visible Laser 650-670nm.
  • Decode Capability: Code11, Code39, Code93, Code32, Code128, Coda Bar, UPC-A, UPC-E, EAN-8, EAN-13, ISBN/ISSN, JAN.EAN/UPC Add-on2/5 MSI/Plessey, Telepen and China Postal Code,Interleaved 2 of 5, Industrial 2 of 5, Matrix 2 of 5, etc ; 300 configurable options for prefix, suffix and termination strings, support turn on/off the beep.
  • Color: Black. Dimensions: 3.6 x 2.6 x 6.1 inches. Type of Cable: 2M or 6ft straight cable. Shock: 1.5m drop on concrete surface. Regulatory Approvals: FCC CE.

How do I add scrollbars to a Tkinter table?

Connect each scrollbar to the corresponding Treeview view method, and connect the Treeview’s scroll callback back to the scrollbar. The following grid layout supports both vertical and horizontal scrolling while expanding with its parent window:

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 reciprocal connections: the scrollbar’s command lets it move the table, while yscrollcommand or xscrollcommand lets the table update the scrollbar position. Use horizontal scrolling when the combined column widths exceed the available window width.

Rank #2
Eyoyo EYH2 Handheld USB Wired 2D 1D Barcode Scanner for POS Mobile Payment
  • Continuous Usage All Day: The EY-H2 USB barcode scanner is designed to always be ready for the next scan, which significantly reduces downtime and repair costs; it shortens checkout lines, improves customer service, and boosts business productivity
  • Plug and Play: Eyoyo wired barcode scanner is connected via a USB cable, with no need to install any driver or software; It offers effortless connection and is compatible with Windows, Mac, Android, and Linux; Seamlessly works with Quickbook, Word, Excel, Novell, and all common software
  • Supports Multiple 1D/2D Barcodes: Eyoyo QR code scanner scan with most 1D 2D barcodes with ease; 1D Barcodes: EAN, UPC, Code 39, Code 93, Code 128, UCC/EAN 128, Codabar, Interleaved 2 of 5, ITF-6, ITF-14, ISBN, ISSN, MSI-Plessey, GS1 Databar, Code 11, Industrial 25, Matrix 2 of 5, etc. 2D Barcodes: QR, DataMatrix, PDF417, and so on
  • Supports Screen Scanning: The Eyoyo 2D scanner is capable of reading barcodes from smartphone screens, such as mobile coupons, digital wallets, and digital loyalty cards; Before scanning, simply turn your screen brightness to the maximum
  • Sturdy Anti-Shock and Durable Design: The Eyoyo 2D barcode scanner features an ergonomic design made of high-quality ABS, enabling it to withstand repeated drops from 5 ft/1.5 m high onto the concrete ground; The durable plastic material ensures a long service life

How do I sort a Treeview by clicking a column heading?

Treeview does not choose a sort order for your application. Attach a callback to each heading, sort the existing item IDs by that column’s value, then move those items into the new order. This example toggles ascending and descending order per column and treats the score column as numeric:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sort_state = {}

def sort_by(column):
    descending = sort_state.get(column, False)
    items = [(tree.set(iid, column), iid) for iid in tree.get_children("")]

    if column == "score":
        items.sort(key=lambda pair: int(pair[0]), reverse=descending)
    else:
        items.sort(key=lambda pair: pair[0].casefold(), reverse=descending)

    for index, (_, iid) in enumerate(items):
        tree.move(iid, "", index)

    sort_state[column] = not descending

for column in columns:
    tree.heading(column, command=lambda col=column: sort_by(col))

The default values read from Treeview are strings. A plain text sort can therefore put 9,500 after 82,000. Convert numbers to the correct numeric type before comparing them; for dates or locale-formatted numbers, parse the actual data format rather than relying on string order. The example assumes integer scores; adapt conversion and handle invalid or empty values if your data permits them.

Rank #3
Sale
Tera Barcode Scanner Wireless 1D Laser Cordless Barcode Reader with Battery Level Indicator, Versatile 2 in 1 2.4Ghz Wireless and USB 2.0 Wired
  • Larger battery enables longer continuous usage and twice the stand-by time. With the unique battery indicator light showing the remaining battery level, no more Low Battery Anxiety.
  • The curved handle is extended and widened. With specially designed smooth and flat trigger for a better grip.
  • The orange anti shock silicone protective cover can prevent scratches and friction even when dropped from up to 6.56 feet. IP54 technology protects the wireless barcode scanner from dust.
  • Plug and play with the USB receiver or the USB cable, no driver installation needed. Easy and quick to set up. Wireless transmission distance reaches up to 328 ft. in barrier free environment.
  • Supports almost all 1D Barcodes: Febraban Bank Code, Codabar, Code 11, Code93, MSI, Code 128, EAN-128, Code 39, EAN-8, EAN-13, UPC-A, ISBN, Industrial 25, Interleaved 25, Standard 25, Matrix. Reads damaged, fuzzy, reflective and smudged barcodes.

How do I edit a Treeview row?

For a form-style editor, use <<TreeviewSelect>> to load the selected item into Tkinter input widgets. After validating the values, update the item with tree.item(iid, values=new_values). This approach is straightforward when users can select a row, edit its fields elsewhere in the window, and save the changes.

How do I edit a Treeview cell in place?

For spreadsheet-like in-place editing, create an Entry widget over the selected cell. Identify the row and displayed column from a double-click, retrieve that cell’s rectangle, and position the Entry there. On save, replace the matching value in the item’s values.

Rank #4
NetumScan USB 1D Barcode Scanner, Handheld Wired CCD Barcode Reader (1)
  • CCD Image Scanning Technology - NetumScan 1D barcode reader is equiped with advanced CCD sensor, which can quick capture 1D codes from paper and screen, including CODE128, UPC/EAN Add on 2 or 5, that can read even deformed barcodes, i.e. smudged, damaged, fuzzy, reflective barcodes, etc. Reading faster and more accurate than laser scanner.
  • Sturdy Anti-shock and Durable Design - Ergonomic design with high-quality ABS making it can support withstand repeated drops from 2m high to the concrete ground, durable to use. Durable plastic material guarantees long service life.
  • Three scanning mode - Key trigger mode + Auto-induction mode + Continuous Mode. There is no need to pull the trigger in auto-sensing mode and continuous scanning. Sometimes the self-sensing scanning function is in the inactive stage, please contact us and be at your service at any time.
  • Supported 1D Bar Code - 1D Decode Capability: UPC-A, UPC-E, EAN-8, EAN-13, ISSN, ISBN, Code 128, GS1-128, Code39, Code93,Code32, Code11, UCC/EAN128, Interleaved 2 of 5, Industrial 2 of 5, Codabar(NW-7), MSI, Plessey, RSS, China Post, etc.
  • Widely Use Range - This NetumScan Handheld USB barcode scanner can be used in supermarkets, convenience stores, warehouse, library, bookstore, drugstore, retail shop for file management, inventory tracking and POS(point of sale), etc.
def begin_edit(event):
    iid = tree.identify_row(event.y)
    displayed_column = tree.identify_column(event.x)
    if not iid or not displayed_column:
        return

    # Map the displayed column identifier to a data-column position.
    data_index = int(displayed_column.removeprefix("#")) - 1
    if data_index < 0 or data_index >= len(columns):
        return

    column = columns[data_index]
    box = tree.bbox(iid, column)
    if not box:
        return

    x, y, width, height = box
    values = list(tree.item(iid, "values"))
    editor = ttk.Entry(tree)
    editor.place(x=x, y=y, width=width, height=height)
    editor.insert(0, values[data_index])
    editor.focus_set()

    def save(event=None):
        values[data_index] = editor.get()
        tree.item(iid, values=values)
        editor.destroy()

    def cancel(event=None):
        editor.destroy()

    editor.bind("<Return>", save)
    editor.bind("<FocusOut>", save)
    editor.bind("<Escape>", cancel)

tree.bind("<Double-1>", begin_edit)

This mapping assumes the table displays only its named data columns with show="headings". If you show the tree column or reorder displayed columns, adjust the mapping to match the displayed layout. A cell without a visible rectangle—for example, one outside the viewport—cannot be overlaid, so the empty-rectangle check prevents an editor from being placed incorrectly. Add validation before saving if cells have required formats or domain rules.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How do I search or filter Treeview rows?

Keep the original records in a Python collection separate from the visible Treeview items. When the search text changes, clear the visible items and insert only matching records. This example searches all fields for a case-insensitive substring:

Best Value
NetumScan Desktop Barcode Scanner, USB QR Code Reader
  • 【Omnidirectional Automatic Barcode scanner】NetumScan Barcode Scanner can easily capture bar codes 1D, 2D/QR on labels, paper, and mobile phone or computer displays,Sensitive and accurately and you can easily scan damaged barcode, distortion barcode, colorful barcode and reflective barcode, etc special barcode. Perfect for retail and other high-volume scanning applications.
  • 【Automatic Smart Sensing Scanning】Specially equipped induction trigger, the desktop barcode scanner support auto-sensing scanning, barcode recognition more intelligent. When you not use the barcode scanner for a while, it will be into a sleeping mode. When handsfree barcode scanner in sleeping mode, it will automatically be activated once the item moving, and read the barcode under the window to upload to your device.
  • 【Non-slip Base and Anti-shock Design】Our Handsfree Omnidirectional Barcode Scanner can be directly placed on the desk, the anti-slip base makes it more stable, Built-in anti-vibration system can avoid damage while falling from the height of 4.92 feet. IP54 technology protects the wireless barcode scanner from dust.
  • 【Improve Your Efficiency】Compared with handheld barcode scanner, our handsfree barcode scanner is more free of your hands, no need to pick up the scanner when scanning, whether it is cashier scanning goods, or customer scanning digital barcode from smart phone. It can improve work efficiency and save time. Also it is so easy to use, no need extra training necessary for new staff.
  • 【Plug and Play, Easy to Use】No need to install any software or app, Our desktop barcode scanner is Plug and play. Easily connected with your laptop, PC, POS by USB Cable. Ideal work for Windows XP/7/8/10, Mac OS, Linux.(Note:NOT compatible with Square/Clover/Shopify.)
rows = [("Ari", "London", 92), ("Bo", "Leeds", 85)]
query = tk.StringVar()

def refresh(*_):
    needle = query.get().casefold()
    tree.delete(*tree.get_children())
    for row in rows:
        if needle in " ".join(map(str, row)).casefold():
            tree.insert("", "end", values=row)

query.trace_add("write", refresh)
search_box = ttk.Entry(root, textvariable=query)
search_box.pack(fill="x")
refresh()

To search only selected fields, build the searchable text from those fields rather than joining the entire row. Change the predicate for prefix or exact matches. For large collections, repeated full-table rebuilding may make the interface feel unresponsive; the cited examples do not establish a dataset-size threshold, so measure with your own data and keep expensive work off the UI event path.

How do I style Treeview headings and rows?

Use ttk.Style for themed-widget appearance 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 Windows’ default vista theme ignores heading background colors in its example and switches to clam. Treat that as a theme-specific observation, not a universal rule, and verify the result on the operating systems and Tk themes you support.

Runtime version matters for newer visual options. The Python reference notes Treeview additions in Tk 9.0, including striped rows and frozen title columns or items, and in Tk 9.1, including rowheight and headingheight. Check the Tk runtime actually used by the Python installation before depending on those options.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When should I use something other than Treeview?

Choose based on how users interact with the data:

Need Treeview Entry grid or another grid widget
Row selection and a conventional table view Fits the standard-library approach; selection is built into the widget. Requires implementing selection behavior if needed.
Always-editable cells Requires custom in-cell editor logic; it is not built-in spreadsheet editing. Often a better fit when each cell should behave like an input field.
Sorting and search Attach callbacks and filtering logic in application code. Depends on the grid component; verify its APIs and behavior.
Scrolling Connect standard horizontal and vertical scrollbars to xview and yview. Depends on the chosen grid and its integration.

Treeview is a sensible starting point for selectable rows and custom interactions without adding a package dependency. An Entry grid or third-party component may better suit spreadsheet-style editing. Python Guides mentions tksheet, and ttkbootstrap documents a Tableview wrapper with sorting, search, and pagination; neither is part of Python’s standard library. Check a third-party project’s current compatibility, maintenance, and license before adopting it.

Version and example notes

The Python Guides tutorial, last modified September 22, 2026, reports running its examples with Python 3.12.5 and Tk 8.6.13 on Windows 11. That is the tutorial author’s reported environment, not an independent guarantee that every example here works unchanged on every platform or runtime. The fundamental Treeview, heading, item, and scrollbar APIs are documented by Python; newer Tk-specific options should be checked against the runtime in use.

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.