Delegate Table View, PySide6

Pyside6 format number column of QSqlTableModel using QItemDelegate, show number as 9,999,999.99

Answer:

To format a number column in QSqlTableModel using QItemDelegate in PySide6 and display numbers as 9,999,999.99, we need to create a custom delegate. The custom delegate will format the display of the numbers in the desired format.

Here’s a step-by-step example to achieve this:

  1. Create a custom delegate class to format the numbers.
  2. Set the custom delegate to the specific column of your table view.

Here is the complete example:

python
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QTableView, QStyledItemDelegate
from PySide6.QtSql import QSqlDatabase, QSqlTableModel
from PySide6.QtCore import Qt
from PySide6.QtGui import QDoubleValidator
import locale

class NumberFormatDelegate(QStyledItemDelegate):
    def displayText(self, value, locale):
        # Format the number with commas and two decimal places
        return locale.toString(float(value), 'f', 2) if value else ""

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Set up the database connection
        db = QSqlDatabase.addDatabase("QSQLITE")
        db.setDatabaseName(":memory:")
        if not db.open():
            print("Unable to open data source")
            return

        # Create a sample table and populate with sample data
        query = db.exec("""
            CREATE TABLE numbers (
                id INTEGER PRIMARY KEY,
                value REAL
            )
        """)
        query.exec("INSERT INTO numbers (value) VALUES (1234567.89)")
        query.exec("INSERT INTO numbers (value) VALUES (2345678.12)")
        query.exec("INSERT INTO numbers (value) VALUES (3456789.45)")
        query.exec("INSERT INTO numbers (value) VALUES (4567890.67)")

        # Set up the model
        self.model = QSqlTableModel(self, db)
        self.model.setTable("numbers")
        self.model.select()

        # Set up the table view
        self.table_view = QTableView()
        self.table_view.setModel(self.model)
        self.setCentralWidget(self.table_view)

        # Set the custom delegate for the 'value' column
        self.table_view.setItemDelegateForColumn(1, NumberFormatDelegate(self.table_view))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyle("Fusion")  # Optional: Set the application style
    locale.setlocale(locale.LC_ALL, '')  # Set locale for number formatting

    main_win = MainWindow()
    main_win.show()
    sys.exit(app.exec())

Explanation:

  1. NumberFormatDelegate Class:
    • displayText Method: Overrides the method to format the numbers using the locale.toString method, which formats the number with commas and two decimal places. If the value is empty, it returns an empty string.
  2. MainWindow Class:
    • Database Setup: Creates an in-memory SQLite database, a sample table numbers, and populates it with some sample data.
    • Model Setup: Uses QSqlTableModel to load data from the database.
    • Table View Setup: Sets up a QTableView to display the data and assigns the custom delegate to the ‘value’ column (column index 1).
  3. Application Setup:
    • Setting Style: Optionally sets the application style to “Fusion” for a modern look.
    • Locale Setup: Sets the locale for number formatting.

This example demonstrates how to format the number column in a QSqlTableModel using QItemDelegate to display numbers in the format 9,999,999.99. Let me know if you have any questions or need further assistance!

does not work, it show number as 1234567.89

Thanks for the feedback. It seems that the locale.toString method is not formatting the number as expected. Let’s use the format function instead to ensure the number is displayed correctly with commas.

Here’s the updated code to format the number:

python
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QTableView, QStyledItemDelegate
from PySide6.QtSql import QSqlDatabase, QSqlTableModel
from PySide6.QtCore import Qt
from PySide6.QtGui import QDoubleValidator
import locale

class NumberFormatDelegate(QStyledItemDelegate):
    def displayText(self, value, locale):
        # Format the number with commas and two decimal places
        try:
            number = float(value)
            return "{:,.2f}".format(number)
        except ValueError:
            return value

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Set up the database connection
        db = QSqlDatabase.addDatabase("QSQLITE")
        db.setDatabaseName(":memory:")
        if not db.open():
            print("Unable to open data source")
            return

        # Create a sample table and populate with sample data
        query = db.exec("""
            CREATE TABLE numbers (
                id INTEGER PRIMARY KEY,
                value REAL
            )
        """)
        query.exec("INSERT INTO numbers (value) VALUES (1234567.89)")
        query.exec("INSERT INTO numbers (value) VALUES (2345678.12)")
        query.exec("INSERT INTO numbers (value) VALUES (3456789.45)")
        query.exec("INSERT INTO numbers (value) VALUES (4567890.67)")

        # Set up the model
        self.model = QSqlTableModel(self, db)
        self.model.setTable("numbers")
        self.model.select()

        # Set up the table view
        self.table_view = QTableView()
        self.table_view.setModel(self.model)
        self.setCentralWidget(self.table_view)

        # Set the custom delegate for the 'value' column
        self.table_view.setItemDelegateForColumn(1, NumberFormatDelegate(self.table_view))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyle("Fusion")  # Optional: Set the application style
    locale.setlocale(locale.LC_ALL, '')  # Set locale for number formatting

    main_win = MainWindow()
    main_win.show()
    sys.exit(app.exec())

In this version:

  • The NumberFormatDelegate class’s displayText method uses Python’s format function to format the number with commas and two decimal places.

This should display numbers in the desired format, such as 1,234,567.89. Try this and let me know if it works better for you!

 

Leave a Reply

The maximum upload file size: 500 MB. You can upload: image, audio, video, document, spreadsheet, interactive, other. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop file here