2
\$\begingroup\$

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.

Confettimaker
7812 gold badges8 silver badges20 bronze badges
asked Aug 29, 2019 at 16:55
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Sorry, but I thought you overdid it with loops in the load_data method.

Try your example with the load_data method, which looks like this:

# ...
def load_data(self): 
 options = QFileDialog.Options()
 fileName, _ = QFileDialog.getOpenFileName(None,"Title..", "",
 "Text Files (*.txt)", options=options)
 if fileName:
 self.tableWidget.setRowCount(0) 
 self.x_val, self.y_val = np.loadtxt(fileName, usecols=(0,1), unpack = True, delimiter =',') 
 for row in range(len(self.x_val)):
 self.tableWidget.insertRow(row)
 self.tableWidget.setItem(row, 0, QtWidgets.QTableWidgetItem(str(self.x_val[row])))
 self.tableWidget.setItem(row, 1, QtWidgets.QTableWidgetItem(str(self.y_val[row])))
 self.tableWidget.resizeColumnsToContents()
# ...
answered Oct 4, 2019 at 22:14
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.