Home > Enterprise >  Qthread isn't working Not returning signals
Qthread isn't working Not returning signals

Time:07-09

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()

  • Related