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.
0ms
5ms
11ms
20ms
27ms
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 = datetime.datetime.now().strftime("%H:%M:%S") data = [QTableWidgetItem(number), QTableWidgetItem(update_time), QTableWidgetItem(f'{update_speed:.2f}'), QTableWidgetItem(update_time)] if not update_is_new: self.live_output_number.removeRow(updated_row) self.live_output_number.insertRow(updated_row) 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. -
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.
-
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 orelse
case) with something likereturn super(UnitDataModel, self).data(index, role)
For your case (updates etc.) you should also handle the
Qt.EditRole
role case, returningrow[column]
.Meanwhile, for insertions/deletions you need to implement the methods detailed in https://doc.qt.io/qt-5/qabstracttablemodel.html#subclassing. 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". -
From where should that dictionary value be updated ?