theozh
theozh

Reputation: 25714

Incomplete population of QTableWidget after sorting

I have a QTableWidget which will be populated with some random values. The table has sorting enabled: tableWidget.setSortingEnabled(True). Sorting works fine (I know, in this minimal example it will be alphanumerical sort of numbers).

However, when I've sorted the table by one column, then clearing the table with various suggestions here on SO, either tableWidget.clear(), tableWidget.clearContent() or tableWidget.setRowCount(0) and repopulate the table, the table will be populated incompletely. I already noticed that the table will be imcompletely populated until the column which is sorted. So sorting the last column would result in a completely refilled table. But that's not an acceptable workaround.

But what am I missing here? How to always fully re-populate the table?

Code:

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QAction, QTableWidget, QTableWidgetItem, QVBoxLayout, QPushButton
from PyQt5.QtCore import pyqtSlot
import random

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 table'
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(0,0,700,500)
        self.layout = QVBoxLayout()

        self.tableWidget = QTableWidget()
        self.tableWidget.setSortingEnabled(True)
        self.layout.addWidget(self.tableWidget)

        self.pb_refill = QPushButton("Refill")
        self.pb_refill.clicked.connect(self.on_click_pb_refill)
        self.layout.addWidget(self.pb_refill)

        self.setLayout(self.layout) 
        self.show()

    @pyqtSlot()
    def on_click_pb_refill(self):
        # self.tableWidget.clear()
        # self.tableWidget.clearContents()
        self.tableWidget.setRowCount(0)
        rows_random = int(random.random()*7)+5
        self.tableWidget.setRowCount(rows_random)
        self.tableWidget.setColumnCount(6)
        for row in range(rows_random):
            for col in range(6):
                number = random.random()
                self.tableWidget.setItem(row, col, QTableWidgetItem(str(number)))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

Result: (after sorting and refill)

enter image description here

Upvotes: 2

Views: 531

Answers (1)

eyllanesc
eyllanesc

Reputation: 243907

The problem is that while you are adding items you are reordering, for example let's say you have inserted the value of the first row correctly but then you enter a new item in (1, 0) that is less than the item (0, 0) by what will be reordered (items (0, j) will be (1, j)), and when you insert you set item (1, 1) will replace the item that occupied position (0, 1) so item (0 , 2) will remain empty.

The solution is to disable sorting by populating the table.

@pyqtSlot()
def on_click_pb_refill(self):
    self.tableWidget.clear()
    self.tableWidget.setSortingEnabled(False)
    rows_random = int(random.random() * 7) + 5
    self.tableWidget.setRowCount(rows_random)
    self.tableWidget.setColumnCount(6)
    for row in range(rows_random):
        for col in range(6):
            number = random.random()
            self.tableWidget.setItem(row, col, QTableWidgetItem(str(number)))
    self.tableWidget.setSortingEnabled(True)

Upvotes: 4

Related Questions