I'm doing a larger PyQt5 project which includes loading in large amount of data into a QTableWidget. However filling the table up with the loaded data is extremely slow due to nested for loops. I put there a minimal working example. The loaded .txt files usually look like this:
...
3.137856026645493124e+00,-1.018072816226149244e-02
3.137333399059442751e+00,2.133285461296379468e-04
3.136810945537534145e+00,6.040261342268495991e-04
3.136288665992822633e+00,6.455403916425843380e-03
3.135766560338420383e+00,3.788118428284327315e-03
3.135244628487498630e+00,3.439159817145511638e-02
3.134722870353285007e+00,-8.456704230609860635e-04
3.134201285849066654e+00,2.062391644217435177e-02
3.133679874888186667e+00,-1.154215762495692556e-02
3.133158637384046763e+00,-3.520437354375163114e-02
3.132637573250105945e+00,4.354430655996290934e-05
...
main.py
from PyQt5.QtWidgets import QFileDialog
from PyQt5 import QtWidgets, QtCore
import numpy as np
from ui import Ui_MainWindow
class MainProgram(QtWidgets.QMainWindow, Ui_MainWindow):
x_val = np.array([])
y_val = np.array([])
def __init__(self, parent = None):
super(MainProgram, self).__init__(parent)
self.setupUi(self)
self.tableWidget.setColumnCount(2)
self.tableWidget.setRowCount(5)
self.tableWidget.setHorizontalHeaderLabels(["Angular frequency", "Intensity"])
self.tableWidget.setSizeAdjustPolicy(
QtWidgets.QAbstractScrollArea.AdjustToContents)
self.btn_load.clicked.connect(self.load_data)
def load_data(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getOpenFileName(None,"Title..", "",
"All Files (*);;Text Files (*.txt)", options=options)
try:
if fileName:
self.tableWidget.setRowCount(0)
self.x_val, self.y_val = np.loadtxt(fileName, usecols=(0,1), unpack = True, delimiter =',')
""" as you can see I limit the max lines, but even at max 800
it's slow"""
if len(self.x_val)<800:
for row_number in range(len(self.x_val)):
self.tableWidget.insertRow(row_number)
for item in range(len(self.x_val)):
self.tableWidget.setItem(item, 0, QtWidgets.QTableWidgetItem(str(self.x_val[item])))
for item in range(len(self.y_val)):
self.tableWidget.setItem(item, 1, QtWidgets.QTableWidgetItem(str(self.y_val[item])))
else:
for row_number in range(800):
self.tableWidget.insertRow(row_number)
for item in range(800):
self.tableWidget.setItem(item, 0, QtWidgets.QTableWidgetItem(str(self.x_val[item])))
for item in range(800):
self.tableWidget.setItem(item, 1, QtWidgets.QTableWidgetItem(str(self.y_val[item])))
self.tableWidget.resizeRowsToContents()
self.tableWidget.resizeColumnsToContents()
except Exception as e:
print(e)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
my_interface = MainProgram()
my_interface.show()
sys.exit(app.exec_())
ui.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.btn_load = QtWidgets.QPushButton(self.centralwidget)
self.btn_load.setObjectName("btn_load")
self.verticalLayout.addWidget(self.btn_load)
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(0)
self.tableWidget.setRowCount(0)
self.verticalLayout.addWidget(self.tableWidget)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.btn_load.setText(_translate("MainWindow", "Load"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
My question is: Can this be optimized in any way? Thank you for answering.