Search code examples
pythonpyqt5qtablewidget

I want to sum up an entire column in a QTableWidget


I'm creating a spreadsheet in PyQt5 and I'm trying to add mathematical functionality. Is there a way to sum up the contents of an entire column either by calling the column Horizontal Header Label or the number of the column?

enter image description here

For example, how would I sum up the contents of the 'Gas' column from this QTableWidget below?


Solution

  • You have to use itemChanged which is emitted when a QTableWidgetItem changes.

    import random
    import sys
    
    from PyQt5.QtCore import Qt
    from PyQt5.QtWidgets import (
        QApplication,
        QMainWindow,
        QSpinBox,
        QStyledItemDelegate,
        QTableWidget,
        QTableWidgetItem,
    )
    
    COLUMN = 2
    
    
    class Delegate(QStyledItemDelegate):
        def createEditor(self, parent, option, index):
            return QSpinBox(parent=parent, minimum=0, maximum=1000)
    
    
    class MainWindow(QMainWindow):
        def __init__(self, parent=None):
            super().__init__(parent)
    
            self.table = QTableWidget(10, 10)
            self.table.itemChanged.connect(self.handle_item_changed)
            delegate = Delegate(self.table)
            self.table.setItemDelegateForColumn(COLUMN, delegate)
            self.table.setHorizontalHeaderItem(COLUMN, QTableWidgetItem("Gas"))
    
            for i in range(5):
                value = random.randint(3, 10)
                item = QTableWidgetItem()
                item.setData(Qt.DisplayRole, value)
                self.table.setItem(i, COLUMN, item)
    
            self.setCentralWidget(self.table)
    
        def handle_item_changed(self, item):
            if item.column() == COLUMN:
                r = 0
                for i in range(self.table.rowCount()):
                    item = self.table.item(i, COLUMN)
                    if item:
                        value = item.data(Qt.DisplayRole)
                        if isinstance(value, int):
                            r += value
                print(f"sum = {r}")
    
    
    def main():
        app = QApplication(sys.argv)
        view = MainWindow()
        view.resize(640, 480)
        view.show()
        sys.exit(app.exec_())
    
    
    if __name__ == "__main__":
        main()