Important: Please read the Qt Code of Conduct -

PySide2 QTablewidget expected behavior?

  • I have a 4 column QTableWidget that can grow to a few thousand rows.
    As data comes in it is either a new row or an update to an existing row.
    A new row had its position calculated then was created at that position and filled with data.
    An updated row had its position calculated then the elements were updated.
    However as the table grew the updates started to take longer and longer, I created simple time() print logging and a new row registered as 0ms however as updates happened the time taken would go something like.
    and just keep growing until the software just froze.
    However after some tinkering if I added extra code to delete the old row then add it again and populate it the most time I see is 1ms to update.
    Snippet of code.

            if number not in self.number_table_dict.keys():
                update_is_new = 1
            self.number_table_dict[number] = [update_time, update_speed]
            updated_row = list(sorted(self.number_table_dict.keys())).index(number)
            update_time ="%H:%M:%S")
            data = [QTableWidgetItem(number), QTableWidgetItem(update_time),
            if not update_is_new:
            for i in range(0, 4):
                self.live_output_number.setItem(updated_row, i, data[i])

    Above is the fast code, the only difference being that I was only adding a new row if needed and not deleting an existing one first.
    I did see a post where PySide2 had update issues compared to PyQt5 but it was marked as fixed.
    I am on 5.13.1
    Is this the expected behavior for an update or a problem.

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Intriguing indeed, however, why not have a custom table model on top of your dictionary ? That would remove a level of indirection.

  • Thanks, I will have a look at custom models, I am pretty new to QT5 and making it up as I go along with Google's assistance.

  • Lifetime Qt Champion

    Then QAbstractTableModel will be your friend.

  • I have been looking all day at examples and videos but they seem to be either to simple or far to complicated for what I need. Do you have any examples with a read only table that would update as data comes in to the dictionary?

    So far my model is like this

    class UnitDataModel(QAbstractTableModel):
        def __init__(self, units=None):
            super(UnitDataModel, self).__init__()
            self.units = units or {}
            self.columns = ['ISSI', 'Time', 'Speed', 'Update Time']
        def data(self, index, role):
            row = self.units[index.row()]
            column = self.columns[index.column()]
            if role == Qt.DisplayRole:
                return str(row[column])
        def rowCount(self, *args, **kwargs):
            return len(self.units.keys())
        def columnCount(self, *args, **kwargs):
            return len(self.columns)
        def headerData(self, section, orientation, role:Qt.DisplayRole):
            if orientation == Qt.Horizontal and role == Qt.DisplayRole:
                return self.columns[section]

    I think I need an addrow function and maybe a sort.

  • @Stephen-Hall said in PySide2 QTablewidget expected behavior?:

    . Do you have any examples with a read only table that would update as data comes in to the dictionary?

    It's not read-only if you can update it!

    Your data() function should end (unconditional or else case) with something like

    return super(UnitDataModel, self).data(index, role)

    For your case (updates etc.) you should also handle the Qt.EditRole role case, returning row[column].

    Meanwhile, for insertions/deletions you need to implement the methods detailed in And to allow updates you need to implement setData() method. You need to tie them to whatever happens when you say "would update as data comes in to the dictionary".

  • Lifetime Qt Champion

    From where should that dictionary value be updated ?

Log in to reply