DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
World desk3 min

PyQt6 QTableWidget: Build, Style, and Read a Table

A practical PyQt6 QTableWidget guide: create a table, populate and style cells, retrieve text safely, and understand when QTableView is a better fit.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use QTableWidget for a straightforward item-based table: set its dimensions and headers, add a QTableWidgetItem for each populated cell, and read values back through those items. The example below builds a small table, colors a cell, and safely retrieves its text.

Build and populate a QTableWidget

QTableWidget is a convenient item-based table widget with a default model, so you can add cell items directly without creating a separate table model. Install the PyQt6 package with pip install PyQt6, then create the widget and populate it:

As an Amazon Associate I earn from qualifying purchases.

import sys

from PyQt6.QtGui import QColor
from PyQt6.QtWidgets import QApplication, QTableWidget, QTableWidgetItem

app = QApplication(sys.argv)

table = QTableWidget(3, 2)
table.setHorizontalHeaderLabels(["Product", "Quantity"])

rows = [
    ("Notebook", 12),
    ("Pen", 30),
    ("Folder", 8),
]

for row_index, (product, quantity) in enumerate(rows):
    table.setItem(row_index, 0, QTableWidgetItem(str(product)))
    table.setItem(row_index, 1, QTableWidgetItem(str(quantity)))

table.item(0, 0).setBackground(QColor("#d9edff"))

table.resizeColumnsToContents()
table.show()
sys.exit(app.exec())

The constructor arguments in QTableWidget(3, 2) specify three rows and two columns. setHorizontalHeaderLabels() names the columns. For each cell, create a QTableWidgetItem and pass it to setItem(row, column, item). Convert values to strings deliberately for display; the example converts the numeric quantities too.

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

After insertion, the table takes ownership of the item. Create and insert a distinct item for each populated cell rather than trying to reuse one item in multiple cells. The code follows the PyQt6 module layout; Qt for Python’s tutorial uses PySide6 imports, so its examples should not be copied with those imports into a PyQt6 application. See the Riverbank PyQt product page for package information and the Qt for Python QTableWidget reference for widget behavior.

Style cells and control the table’s appearance

For a one-off cell color, set the item background to a QColor, as the example does. You can also set an item’s foreground or text alignment when those properties are useful for the data. The Qt for Python table-widget tutorial demonstrates per-item background coloring; in PyQt6, import QColor from PyQt6.QtGui.

For broader appearance changes, use item-view styling. When you need custom rendering or editor behavior, a delegate is generally the better place to implement it; Qt’s model/view overview describes QStyledItemDelegate for custom delegates and style-sheet work. See the Qt model/view programming overview.

Read a cell safely

Call item(row, column) to get the cell’s item, then read its text. An unset cell has no item, so check for None before calling text():

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
row = 0
column = 0
item = table.item(row, column)

if item is not None:
    print(item.text())
else:
    print("That cell is empty")

Use rowCount() and columnCount() to inspect the current dimensions and iterate only over valid coordinates:

for row in range(table.rowCount()):
    values = []
    for column in range(table.columnCount()):
        item = table.item(row, column)
        values.append(item.text() if item is not None else "")
    print(values)

Handle edits and sorting without mismatching rows

To respond to edits, connect to itemChanged(item) when you need the changed item, or cellChanged(row, column) when its coordinates are sufficient. These signals report data changes; a click signal answers a different question and should not be used as a substitute for edit notification. See the QTableWidget signal reference.

When adding multiple cells to each record, populate the table before enabling sorting. If sorting is active on the column being populated, inserting an item can move its row immediately. Later calls that continue using the original row number may then write values into a different record. If sorting must remain enabled, temporarily disable it while filling a row, then restore it after the row is complete. The behavior is documented in the Qt QTableWidget reference.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Choose between QTableWidget and QTableView

Choose based on where the data lives and how much control the application needs over its model:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Question QTableWidget QTableView with a model
Where are cell values represented? As widget-managed QTableWidgetItem objects. In a separate model supplied to the view.
What setup is it suited to? Directly adding items to a straightforward table. Applications that need a custom or reusable data model.
Which offers more model control? Less control; the widget uses its default model. More control over how data is represented and supplied.

Qt’s guidance is direct: “If you want a table that uses your own data model you should use QTableView rather than this class.” That recommendation appears in the official Qt for Python QTableWidget documentation. The documentation does not give a row-count threshold at which one widget becomes preferable; base the choice on whether direct item management or a separate model fits your application.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.