1 year ago

#73207

test-img

pupinho

How to fill QStandardItemModel with bigdata if setItem works slow?

My task is to fill QStandardItemModel with some rect-shaped bigdata. The Python code is

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import sys
import time


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.resize(540, 220)
        self.table_view = QTableView(self)
        self.table_view.setGeometry(10, 10, 400, 200)
        self.button = QPushButton(self)
        self.button.move(420, 20)
        self.button.setText('Generate!')

        self.table_model = QStandardItemModel(parent=self)

        self.button.clicked.connect(self.button_clicked)

    def button_clicked(self):
        start_time = time.time()

        start_cell = [2, 1]

        for i in range(100):
            for j in range(1000):
                item = QStandardItem('X')
                self.table_model.setItem(start_cell[0] + i, start_cell[1] + j, item)

        self.table_view.setModel(self.table_model)

        print(time.time() - start_time)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

For the first time it works pretty fast (0.2 s at my computer) but for the second time it takes 10s because QTableView is connected with QStandardItemModel self.table_view.setModel(self.table_model)

Could you advice how to disconnect QTableView and QStandardItemModel and if the more optimal way to fill table with bigdata?

===

Thanks to @musicamante the following code was realized. Now table is filled with insertRow() and now it takes ~0.4 sec.

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import sys
import time


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.resize(540, 220)
        self.table_view = QTableView(self)
        self.table_view.setGeometry(10, 10, 400, 200)
        self.button = QPushButton(self)
        self.button.move(420, 20)
        self.button.setText('Paste bigdata')

        self.table_model = QStandardItemModel(parent=self)
        self.table_view.setModel(self.table_model)

        self.button.clicked.connect(self.button_clicked)

        for i in range(10):
            for j in range(10):
                self.table_model.setItem(i, j, QStandardItem(str(10 * i + j)))

    def button_clicked(self):
        start_time = time.time()

        start_row = 2  # coordinates of bigdata array top-left corner
        start_col = 2
      
        for i in range(100):  # number of rows in bigdata array
            row = []
            # Adding cells before array
            for j in range(start_col):
                if self.table_model.item(start_row + i, j) is not None:
                    row.append(QStandardItem(self.table_model.item(start_row + i, j).text()))
                else:
                    row.append(QStandardItem(''))
            # Adding array cells
            for j in range(1000):  # number of columns in bigdata array
                row.append(QStandardItem('X'))
            # Adding cells after array
            for j in range(start_col + 1000, self.table_model.columnCount()-1, 1):
                if self.table_model.item(start_row + i, j) is not None:
                    row.append(QStandardItem(self.table_model.item(start_row + i, j).text()))
                else:
                    row.append(QStandardItem(''))

            self.table_model.insertRow(start_row + i, row)
            self.table_model.removeRows(start_row + i + 1, 1)

        print(time.time() - start_time)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())
    

python

pyqt

qtableview

qstandarditemmodel

0 Answers

Your Answer

Accepted video resources