How would I return multiple lists generated in QThread to the mainthread without blocking the GUI?
I am looking to do time intensive stuff with xlwings in a thread and then when thread is finished I want to be able to use those lists in the mainthread. Is there any easy way of doing this?
I could think of doing something like adding the values from the thread to a global list and access them in the mainthread.
from PyQt5 import QtCore, QtWidgets
import sys
class Ui_Calculations(object):
def setupUi(self, Calculations):
Calculations.setObjectName("Calculations")
Calculations.resize(850, 363)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(Calculations.sizePolicy().hasHeightForWidth())
Calculations.setSizePolicy(sizePolicy)
Calculations.setMinimumSize(QtCore.QSize(850, 350))
Calculations.setMaximumSize(QtCore.QSize(860, 363))
self.centralwidget = QtWidgets.QWidget(Calculations)
self.centralwidget.setObjectName("centralwidget")
Calculations.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(Calculations)
self.menubar.setGeometry(QtCore.QRect(0, 0, 850, 21))
self.menubar.setObjectName("menubar")
self.menuScreenshot = QtWidgets.QMenu(self.menubar)
self.menuScreenshot.setObjectName("menuScreenshot")
Calculations.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(Calculations)
self.statusbar.setObjectName("statusbar")
Calculations.setStatusBar(self.statusbar)
self.actionScreenshot = QtWidgets.QAction(Calculations)
self.actionScreenshot.setObjectName("actionScreenshot")
self.menuScreenshot.addAction(self.actionScreenshot)
self.menubar.addAction(self.menuScreenshot.menuAction())
self.retranslateUi(Calculations)
QtCore.QMetaObject.connectSlotsByName(Calculations)
def retranslateUi(self, Calculations):
_translate = QtCore.QCoreApplication.translate
Calculations.setWindowTitle(_translate("Calculations", "Calculations"))
self.menuScreenshot.setTitle(_translate("Calculations", "File"))
self.actionScreenshot.setText(_translate("Calculations", "Screenshot"))
class mainClass(QtWidgets.QMainWindow, Ui_Calculations):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.thread = exampleThread()
self.thread.finished.connect(self.run_return)
self.thread.start()
def run_return(self):
#do something with return values
print(exampleList[-1])
print(example1List[-1])
class exampleThread(QtCore.QThread):
"""Example thread"""
finished = QtCore.pyqtSignal()
def __init__(self,parent = None):
super().__init__(parent)
def run(self):
exampleList = [5,4,3]
example1List = [5,4,3]
self.finished.emit()
#return exampleList,example1List
def main():
app = QtWidgets.QApplication(sys.argv)
exampleWindow = mainClass()
app.processEvents()
exampleWindow.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You can pass known Python types as parameters when you emit a signal.
In your example, change the declaration of the "signal" to include the data types you want to pass, both of which are of type list
:
finished = QtCore.pyqtSignal(list, list)
Then have the corresponding "slot" accept the two parameters:
def run_return(self, list1, list2):
print(list1[-1])
print(list2[-1])