A PySide6 DataTable widget with jQuery DataTable-like functionality
Project description
PySide6 DataTable
A powerful DataTable widget for PySide6 applications with functionality similar to jQuery DataTable.
Features
- Customizable Table: Easily configure columns, types, and formatting
- Data Type Detection: Automatically detect and handle different data types [NOT-IMPLEMENTED-YET]
- Type-based Sorting: Different column types sort appropriately
- Search Functionality: Global and column-specific search
- Row Collapsing: Support for expandable/collapsible rows
- Pagination: Built-in pagination with configurable page sizes [SEMI-IMPLEMENTED]
- Column Visibility: Show/hide columns easily
- Row Numbering: Show/hide vertical row numbers
- Aggregation Functions: Calculate sums, averages, percentages, etc. [SEMI-IMPLEMENTED]
- Custom Formatting: Format data display for different column types
- Observer Pattern: Event-driven architecture for clear code organization
- Builtin-Delegates: Packages has some useful delegates built-in for popular datatypes (ProgressBar, IconBoolean, ActionButtons)
- Fluent-Interface: Allow you channing calls on most methods of
DataTableinstance (return self)
Installation
pip install pyside6-datatable-widget
Versions - Current Release State
| Version | Date | Notes |
|---|---|---|
| 1.2.2 | 2026-04-03 | - |
| 1.2.1 | 2026-03-25 | - |
| 1.2.0 | 2026-02-10 | - |
Basic Usage
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from datatable import DataTable, DataType
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("DataTable Example")
self.resize(800, 600)
# Create central widget and layout
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
# Create DataTable
self.data_table = DataTable()
layout.addWidget(self.data_table)
# Set up columns (key, header, data_type)
columns = [
("id", "ID", DataType.NUMERIC),
("name", "Name", DataType.STRING),
("age", "Age", DataType.NUMERIC),
("active", "Active", DataType.BOOLEAN),
("progress", "Progress", DataType.PROGRESS)
]
# Set up data
data = [
{"id": 1, "name": "John", "age": 30, "active": True, "progress": 75},
{"id": 2, "name": "Jane", "age": 25, "active": False, "progress": 30},
{"id": 3, "name": "Bob", "age": 40, "active": True, "progress": 100}
]
# Apply to table
self.data_table.setColumns(columns).setData(data)
# Connect signals
self.data_table.rowSelected.connect(self.on_row_selected)
def on_row_selected(self, row, row_data):
print(f"Row {row} selected: {row_data}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
Advanced Features
Custom Column Formatting
from datatable import DataTableModel
# Create model with custom formatting
model = DataTableModel()
model.setFormattingFunction("price", lambda value: f"${value:.2f}")
model.setFormattingFunction("percentage", lambda value: f"{value:.1f}%")
# Set model to table
data_table.setModel(model)
Row Collapsing
# Enable row collapsing
data_table.enableRowCollapsing(True, "subrows")
# Example data with subrows
data = [
{
"id": 1,
"name": "Category A",
"total": 1000,
"subrows": [
{"id": 101, "name": "Item A1", "total": 500},
{"id": 102, "name": "Item A2", "total": 500}
]
},
{
"id": 2,
"name": "Category B",
"total": 2000,
"subrows": [
{"id": 201, "name": "Item B1", "total": 1200},
{"id": 202, "name": "Item B2", "total": 800}
]
}
]
data_table.setData(data)
# Connect expansion signals
data_table.rowExpanded.connect(lambda row, data: print(f"Row {row} expanded"))
data_table.rowCollapsed.connect(lambda row, data: print(f"Row {row} collapsed"))
Aggregation Functions
# Get aggregate values
total = data_table.getAggregateValue("amount", "sum")
average = data_table.getAggregateValue("amount", "avg")
count = data_table.getAggregateValue("id", "count")
# Calculate percentage of a row value relative to total
row_data = data_table.getSelectedRow()
if row_data:
amount = row_data["amount"]
total = data_table.getAggregateValue("amount", "sum")
percentage = data_table.calculateRowPercentage(row_index, "amount")
Custom Search Functions
# Set custom search function for a column
model.setSearchFunction("complex_data", lambda value, term: term in str(value["name"]))
# Search in table
data_table.search("search term")
# Search specific column
matching_rows = model.searchColumn("name", "John")
Built-in Custom Delegates
The library provides several built-in delegates for enhanced data visualization.
Progress Bar Delegate (DataType.PROGRESS_BAR)
A highly customizable progress bar delegate.
- Default Behavior: Displays a progress bar using the theme's highlight color.
- Customization:
setProgressBarColor(column_key, color): Set a static base color.setProgressBarGradient(column_key, enabled): Enable a gradient effect (fade from 0% to 100% opacity).addProgressBarRange(column_key, min_pct, max_pct, color): Add color ranges (e.g., Red for <50%, Green for >80%).
# Configure Progress Bar
self.data_table.setProgressBarColor('completion', "#3b82f6") # Base color
self.data_table.setProgressBarGradient('completion', True) # Enable gradient
# Or use ranges
self.data_table.addProgressBarRange('completion', 0, 50, "#ef4444") # Red for low
self.data_table.addProgressBarRange('completion', 50, 80, "#eab308") # Yellow for medium
self.data_table.addProgressBarRange('completion', 80, 100, "#22c55e") # Green for high
Icon Boolean Delegate (DataType.ICON_BOOLEAN)
Displays boolean values using SVG icons instead of text or checkboxes.
- Default Behavior: Displays a checkmark for
Trueand an 'X' forFalse. - Customization:
setIconBooleanColors(column_key, yes_color, no_color): Customize the colors for the Yes and No states.
# Configure Icon Boolean (defaults are Green/Red)
self.data_table.setIconBooleanColors('status', yes_color="#00FF00", no_color="#FF0000")
Action Buttons Delegate (DataType.ACTION_BUTTONS)
Displays inline action buttons within a cell. Useful for per-row actions like Start, Stop, Delete, Edit, etc.
- Customization:
setActionButtons(column_key, buttonDefs): Configure the buttons for the column.buttonDefsis a list of dictionaries.# button_def dictionary structure: { "key": "action_id", "label": "Button Text", "color": "#HEX_COLOR", "visibleWhen": lambda row_data: True # optional visibility condition }
- Events:
- The table emits
rowActionClicked(column_key, action_key, row_data)when a button is clicked.
- The table emits
# Setup Action Buttons
button_defs = [
{"key": "start", "label": "▶ Start", "color": "#22c55e", "visibleWhen": lambda d: d.get('status') == 'PENDING'},
{"key": "stop", "label": "⏹ Stop", "color": "#ef4444", "visibleWhen": lambda d: d.get('status') == 'RUNNING'}
]
self.data_table.setActionButtons('actions', button_defs)
# Connect to the signal
self.data_table.rowActionClicked.connect(
lambda col, action, data: print(f"Action '{action}' clicked on column '{col}'")
)
API Reference
DataTable
Main widget class that provides the UI and functionality.
Methods
setData(data) -> Self: Set table dataappendRow(row_data) -> bool: Append a row to the tableinsertRow(row_index, row_data) -> bool: Insert a row at a specific indexsetColumns(columns) -> Self: Set table columnssetVisibleColumns(columns) -> Self: Set which columns are visibleenableRowCollapsing(enabled, child_row_key) -> Self: Enable/disable row collapsingsetFormattingFunction(column_key, func) -> Self: Set formatting function. Actually, this method is alias ofModel.setFormattingFunctionsearch(term) -> Self: Search the tablesort(column_key, order) -> Self: Sort the tablesetPage(page) -> Self: Set current pagesetRowsPerPage(rows) -> Self: Set rows per pagegetData(): Get current table datagetSelectedRow(): Get selected row datagetAggregateValue(column_key, agg_type): Get aggregate value for columnsetUiSelectionType(mode, behavior) -> Self: Set selection mode and behavior for the table viewshowRowNumbers(enabled) -> Self: Show or hide row numbers (vertical header)selectAll() -> Self: This is fluent alias ofModel.selectAll()selectNone() -> Self: This is fluent alias ofModel.clearSelection()clearSelection() -> Self: This is fluent alias ofDataTable.selectNone()selectInverse() -> Self: Fluent select inversesetProgressBarColor(column_key, color) -> Self: Set base color for a progress bar columnsetProgressBarGradient(column_key, enabled) -> Self: Enable/disable gradient for a progress bar columnaddProgressBarRange(column_key, min_pct, max_pct, color) -> Self: Add a color range for a progress bar columnsetIconBooleanColors(column_key, yes_color, no_color) -> Self: Set colors for an icon boolean columnsetActionButtons(column_key, buttonDefs) -> Self: Configure inline action buttons for an ACTION_BUTTONS columnconfigureTableView(methodName, *args, **kwargs) -> Self: Generic proxy — delegate anyQTableViewsetter call by name, without coupling to a specific named facade method. Useful for one-off configurations that don't need a dedicated wrapper.
from PySide6.QtWidgets import QAbstractScrollArea
# Prevent row-count-driven sizeHint from expanding the parent window
table.configureTableView('setSizeAdjustPolicy', QAbstractScrollArea.SizeAdjustPolicy.AdjustIgnored)
# Other examples
table.configureTableView('setShowGrid', False)
table.configureTableView('setColumnWidth', 0, 120)
Signals
pageChanged(page): Emitted when page changesrowSelected(row, row_data): Emitted when row is selectedrowExpanded(row, row_data): Emitted when row is expandedrowCollapsed(row, row_data): Emitted when row is collapseddataFiltered(rows): Emitted when data is filteredsortChanged(column, order): Emitted when sort order changesselectionChanged(selected, deselected): Emitted when selection changesrowActionClicked(column_key, action_key, row_data): Emitted when an inline action button is clicked
DataTableModel
Model class that manages data and operations.
Methods
setData(data): Set model datasetColumns(columns): Set model columnssetFormattingFunction(column_key, func): Set formatting functionsetEditableColumns(editable_columns): Set which columns are editablesetVisibleColumns(visible_columns): Set which columns are visiblesetSearchFunction(column_key, func): Set search functionsetSortFunction(column_key, func): Set sort functionsetAggregationFunction(column_key, agg_type, func): Set aggregation functionenableRowCollapsing(enabled, child_row_key): Enable row collapsingsearch(term): Search all rowssearchColumn(column_key, term): Search specific columnaggregate(column_key, agg_type): Aggregate column valuescalculateRowPercentage(row_index, column_key): Calculate row percentage
Signals
rowExpandedCollapsed(int, bool): row, is_expanded. Emitted when a row, sub-rows expanded or collapsed
Note: The model is child class of
QAbstractTableModel. So these signals below are inherited (fromQAbstractItemModel).
dataChanged(topLeft, bottomRight, roles): Emitted when data in the specified range has been modified.headerDataChanged(orientation, first, last): Emitted when header data for a section changes.layoutChanged(): Emitted when layout of the model changes drastically.layoutAboutToBeChanged(): Emitted before a major layout change.modelReset(): Emitted after the model is reset.rowsAboutToBeInserted(parent, start, end): Emitted before rows are inserted.rowsInserted(parent, start, end): Emitted after rows are inserted.rowsAboutToBeRemoved(parent, start, end): Emitted before rows are removed.rowsRemoved(parent, start, end): Emitted after rows are removed.columnsAboutToBeInserted(parent, start, end): Emitted before columns are inserted.columnsInserted(parent, start, end): Emitted after columns are inserted.columnsAboutToBeRemoved(parent, start, end): Emitted before columns are removed.columnsRemoved(parent, start, end): Emitted after columns are removed.rowsMoved(parent, start, end, destination, row): Emitted after rows are moved.columnsMoved(parent, start, end, destination, column): Emitted after columns are moved.
License
This project is licensed under the GNU General Public License v3.0 (GPLv3).
See the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyside6_datatable_widget-1.2.2.tar.gz.
File metadata
- Download URL: pyside6_datatable_widget-1.2.2.tar.gz
- Upload date:
- Size: 56.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e13b6b31aaffc01960bac475c31b4ea5c387ff0c1daaf968e806319347eb11a6
|
|
| MD5 |
0caf425699c5ad034ed4193d9762ba8b
|
|
| BLAKE2b-256 |
b53922ee659405d749d243ae122675c5b7062fa3e0a335a6a4e731e9eb6c2272
|
Provenance
The following attestation bundles were made for pyside6_datatable_widget-1.2.2.tar.gz:
Publisher:
python-publish.yml on ultra-bugs/pyside6-datatable-widget
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyside6_datatable_widget-1.2.2.tar.gz -
Subject digest:
e13b6b31aaffc01960bac475c31b4ea5c387ff0c1daaf968e806319347eb11a6 - Sigstore transparency entry: 1224751425
- Sigstore integration time:
-
Permalink:
ultra-bugs/pyside6-datatable-widget@74033c569d44bd587d0b04df964b64da9172743f -
Branch / Tag:
refs/tags/1.2.2 - Owner: https://github.com/ultra-bugs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@74033c569d44bd587d0b04df964b64da9172743f -
Trigger Event:
release
-
Statement type:
File details
Details for the file pyside6_datatable_widget-1.2.2-py3-none-any.whl.
File metadata
- Download URL: pyside6_datatable_widget-1.2.2-py3-none-any.whl
- Upload date:
- Size: 58.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a70f062c8b2e32dd100212b6d0ce5a6a08a46b09eb81e434230eb972f69af17
|
|
| MD5 |
3836497c7e5bbdedc28114ded0e98a32
|
|
| BLAKE2b-256 |
f6f8c74b827c26ccb987521fd85e4e0fa0810bc0abae22f8ecf39bf1537ee8da
|
Provenance
The following attestation bundles were made for pyside6_datatable_widget-1.2.2-py3-none-any.whl:
Publisher:
python-publish.yml on ultra-bugs/pyside6-datatable-widget
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyside6_datatable_widget-1.2.2-py3-none-any.whl -
Subject digest:
2a70f062c8b2e32dd100212b6d0ce5a6a08a46b09eb81e434230eb972f69af17 - Sigstore transparency entry: 1224751473
- Sigstore integration time:
-
Permalink:
ultra-bugs/pyside6-datatable-widget@74033c569d44bd587d0b04df964b64da9172743f -
Branch / Tag:
refs/tags/1.2.2 - Owner: https://github.com/ultra-bugs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@74033c569d44bd587d0b04df964b64da9172743f -
Trigger Event:
release
-
Statement type: