i have this WorkerSignals class which used to connect signals with the Qthread class worker, SaveToExcel() is a function that i used to run in Qthread.
class WorkerSignals(QObject):
finished = pyqtSignal()
error = pyqtSignal(tuple)
result = pyqtSignal(object)
progress = pyqtSignal(int)
class Worker(QThread):
def __init__(self,query,filename,choices,fileExtension,iterativeornot):
super(Worker,self).__init__()
self.signals = WorkerSignals()
self.query =query
self.filename = filename
self.choices = choices
self.fileExtension = fileExtension
self.iterativeornot =iterativeornot
@pyqtSlot()
def run(self):
try:
SaveToExcel(self.query,self.filename,self.choices,self.fileExtension,self.iterativeornot)
except:
self.signals.result.emit(1)
finally:
self.signals.finished.emit()
this is the class that i used to create the Qwidget that has ui
class AnotherWindow(QWidget):
def __init__(self,windowname):
super().__init__()
self.layout = QVBoxLayout()
self.label = QLabel()
self.setWindowTitle(windowname)
self.setWindowIcon(QIcon(os.path.join(basedir,'./images/import.png')))
self.setFixedSize(460,440)
self.layout.addWidget(self.label)
# Query
self.textinput = QPlainTextEdit()
self.layout.addWidget(self.textinput)
self.qhboxlayout1 = QHBoxLayout()
self.IterativeRadiobtn1 = QRadioButton('All Locations')
self.IterativeRadiobtn2 = QRadioButton('Current Locations')
self.IterativeRadiobtn2.setChecked(True)
self.qhboxlayout1.addWidget(self.IterativeRadiobtn1)
self.qhboxlayout1.addWidget(self.IterativeRadiobtn2)
self.layout.addLayout(self.qhboxlayout1)
# Check boxes
self.c1 = QCheckBox("sc",self)
self.c2 = QCheckBox("ad",self)
self.c3 = QCheckBox("sr",self)
self.c4 = QCheckBox("fc",self)
self.hboxlayoutchoices = QHBoxLayout()
#adding checkboxes to layout
self.checkboxlist = [self.c1,self.c2,self.c3,self.c4]
for cbox in self.checkboxlist:
self.hboxlayoutchoices.addWidget(cbox)
self.layout.addLayout(self.hboxlayoutchoices)
# filename
self.filename = QLineEdit()
self.layout.addWidget(self.filename)
# Combo box to show the filetype which need to be saved
self.extensions = QComboBox()
self.combodict = {'Excel 97-2003 Workbook (*.xls)':'xls','CSV UTF-8 (Comma delimited) (*.csv)':'csv'}
self.extensions.addItems(self.combodict)
self.layout.addWidget(self.extensions)
# import button
self.exportBtn = QPushButton('Import')
self.layout.addWidget(self.exportBtn)
#import function when button clicked
self.exportBtn.clicked.connect(self.IMPORT)
#setting layout
self.setLayout(self.layout)
def RadioButtonCheck(self):
if self.IterativeRadiobtn1.isChecked():
return True
if self.IterativeRadiobtn2.isChecked():
return False
def IMPORT(self):
self.cboxlist = []
for cbox in self.checkboxlist:
if cbox.isChecked():
self.cboxlist.append(cbox.text())
self.textinput.setReadOnly(True)
self.filename.setReadOnly(True)
self.exportBtn.setDisabled(True)
self.saveFilename = self.filename.text()
self.text = self.textinput.toPlainText()
self.inputextension = self.extensions.currentText()
self.getvalue = self.combodict.get(self.inputextension)
self.truorfalse = self.RadioButtonCheck()
# self.queryThread = threading.Thread(target=SaveToExcel,args=(self.text,self.saveFilename,self.cboxlist,self.getvalue,self.truorfalse))
# self.queryThread.start()
self.worker = Worker(self.text,self.saveFilename,self.cboxlist,self.getvalue,self.truorfalse)
self.worktherad = QThread()
self.worker.moveToThread(self.worktherad)
self.worktherad.started.connect(self.worker.run)
self.worktherad.finished.connect(self.complete)
self.worktherad.start()
def complete(self):
self.msg = QMessageBox()
self.msg.setWindowTitle("Status")
self.msg.setText("Import Done")
self.msg.exec()
self.textinput.setReadOnly(False)
self.filename.setReadOnly(False)
self.exportBtn.setDisabled(False)
self.exportBtn.setText("Import Again")
but when i click the import button the function won't run and just do nothing, I don't have a good knowledge about Qthreading but when i use the python default threading the function will run and import the datas. Still i don't have good clear idea about how to implent the Qthreading for the SaveToExcel function.
CodePudding user response:
self.worker = Worker(self.text,self.saveFilename,self.cboxlist,self.getvalue,self.truorfalse)
in this line you should probably pass the parent field and you should accept the parent field in Worker __init__ method and pass it in super call
(so the thread will automatically destroyed once it's parent object is deleted)
and the Worker class is already a QThread you do not need to create another QThread and move it..
you should just run the self.worker by self.worker.start()
and don't forget to connect those Worker signals to valid pyqtSlot and if possible then connect those before starting the self.worker thread
Updated Code Snippet
self.worker = Worker(parent, self.text,self.saveFilename,self.cboxlist,self.getvalue,self.truorfalse) # Accept parent in __init__ method of Worker
self.worktherad.finished.connect(self.complete)
self.worktherad.start()
And also make complete function a pyqtSlot by adding decorator QtCore.pyqtSlot()
