Skip to main content

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 DataTable instance (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 True and an 'X' for False.
  • 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. buttonDefs is 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.
# 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 data
  • appendRow(row_data) -> bool: Append a row to the table
  • insertRow(row_index, row_data) -> bool: Insert a row at a specific index
  • setColumns(columns) -> Self: Set table columns
  • setVisibleColumns(columns) -> Self: Set which columns are visible
  • enableRowCollapsing(enabled, child_row_key) -> Self: Enable/disable row collapsing
  • setFormattingFunction(column_key, func) -> Self: Set formatting function. Actually, this method is alias of Model.setFormattingFunction
  • search(term) -> Self: Search the table
  • sort(column_key, order) -> Self: Sort the table
  • setPage(page) -> Self: Set current page
  • setRowsPerPage(rows) -> Self: Set rows per page
  • getData(): Get current table data
  • getSelectedRow(): Get selected row data
  • getAggregateValue(column_key, agg_type): Get aggregate value for column
  • setUiSelectionType(mode, behavior) -> Self: Set selection mode and behavior for the table view
  • showRowNumbers(enabled) -> Self: Show or hide row numbers (vertical header)
  • selectAll() -> Self: This is fluent alias of Model.selectAll()
  • selectNone() -> Self: This is fluent alias of Model.clearSelection()
  • clearSelection() -> Self: This is fluent alias of DataTable.selectNone()
  • selectInverse() -> Self: Fluent select inverse
  • setProgressBarColor(column_key, color) -> Self: Set base color for a progress bar column
  • setProgressBarGradient(column_key, enabled) -> Self: Enable/disable gradient for a progress bar column
  • addProgressBarRange(column_key, min_pct, max_pct, color) -> Self: Add a color range for a progress bar column
  • setIconBooleanColors(column_key, yes_color, no_color) -> Self: Set colors for an icon boolean column
  • setActionButtons(column_key, buttonDefs) -> Self: Configure inline action buttons for an ACTION_BUTTONS column
  • configureTableView(methodName, *args, **kwargs) -> Self: Generic proxy — delegate any QTableView setter 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 changes
  • rowSelected(row, row_data): Emitted when row is selected
  • rowExpanded(row, row_data): Emitted when row is expanded
  • rowCollapsed(row, row_data): Emitted when row is collapsed
  • dataFiltered(rows): Emitted when data is filtered
  • sortChanged(column, order): Emitted when sort order changes
  • selectionChanged(selected, deselected): Emitted when selection changes
  • rowActionClicked(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 data
  • setColumns(columns): Set model columns
  • setFormattingFunction(column_key, func): Set formatting function
  • setEditableColumns(editable_columns): Set which columns are editable
  • setVisibleColumns(visible_columns): Set which columns are visible
  • setSearchFunction(column_key, func): Set search function
  • setSortFunction(column_key, func): Set sort function
  • setAggregationFunction(column_key, agg_type, func): Set aggregation function
  • enableRowCollapsing(enabled, child_row_key): Enable row collapsing
  • search(term): Search all rows
  • searchColumn(column_key, term): Search specific column
  • aggregate(column_key, agg_type): Aggregate column values
  • calculateRowPercentage(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 (from QAbstractItemModel).

  • 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyside6_datatable_widget-1.2.2.tar.gz (56.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyside6_datatable_widget-1.2.2-py3-none-any.whl (58.4 kB view details)

Uploaded Python 3

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

Hashes for pyside6_datatable_widget-1.2.2.tar.gz
Algorithm Hash digest
SHA256 e13b6b31aaffc01960bac475c31b4ea5c387ff0c1daaf968e806319347eb11a6
MD5 0caf425699c5ad034ed4193d9762ba8b
BLAKE2b-256 b53922ee659405d749d243ae122675c5b7062fa3e0a335a6a4e731e9eb6c2272

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyside6_datatable_widget-1.2.2-py3-none-any.whl.

File metadata

File hashes

Hashes for pyside6_datatable_widget-1.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 2a70f062c8b2e32dd100212b6d0ce5a6a08a46b09eb81e434230eb972f69af17
MD5 3836497c7e5bbdedc28114ded0e98a32
BLAKE2b-256 f6f8c74b827c26ccb987521fd85e4e0fa0810bc0abae22f8ecf39bf1537ee8da

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page