Cannot terminate PyQT QThread

5.7k views Asked by At

This question is related to my previous one

Problem occurs where I'm switching between Alpha to Gamma items too fast. The run() method of GenericThread cannot complete it's loop without error since information given to it changes when i'm switching between items of List1

I've added exeptions but that's not the best workaround in this situation, I have to terminate the thread if it's running and then start it again, but when i'm terminating it, GUI freezez forever (BUT its not like it freeze all the time while switching between items, sometimes self.terminate() works sometimes not and freezes i cant find out why) ...

class GenericThread(QtCore.QThread):
    def __init__(self, parent=None):
        QtCore.QThread.__init__(self, parent)

    def stop(self):
        self.terminate()

    def __del__(self):
        self.quit()
        self.wait()

    def run(self):
        #Some very long stuff
        self.emit( QtCore.SIGNAL('itemSelectionChanged()'))
        return

class MainUI(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self)
        self.ui = Ui_Win()
        self.ui.setupUi(self)

        self.genericThread = GenericThread(self, listIndex=2)
        self.connect(self.genericThread, QtCore.SIGNAL("fillListWithItems(QString, int)"), self.fillListWithItems )
        self.ui.List1.list1SelectedItem.connect(self.fill_List2)
        ...

    def fill_List2(self):
        if self.genericThread.isRunning():
            self.genericThread.stop()
        self.ui.List2.clear()
        list1SelectedItem = str(self.ui.List1.currentItem().text())
        self.genericThread.start()

Now, why does GUI freez and how to termiante self.genericThread correctly ?

1

There are 1 answers

0
PYPL On BEST ANSWER

Based on your comments, @ekhumoro and @Pavel I've fixed my issue and now it runs as i want, well eventhought self.terminate() would be much much better if it worked.

class GenericThread(QtCore.QThread):
    def __init__(self, parent=None):
        QtCore.QThread.__init__(self, parent)
        self.stopFlag = False

    def stop(self):
        self.stopFlag = True

    def __del__(self):
        self.quit()
        self.wait()

    def run(self):
        #Some very long stuff
            if self.stopFlag:
                self.stopFlag = False #Resetting the flag (in my case I have to do this!)
                break #Breaks main loop to finish 'run()'
            else:
                self.emit( QtCore.SIGNAL('itemSelectionChanged()'))

class MainUI(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self)
        self.ui = Ui_Win()
        self.ui.setupUi(self)

        self.genericThread = GenericThread(self, listIndex=2)
        self.connect(self.genericThread, QtCore.SIGNAL("fillListWithItems(QString, int)"), self.fillListWithItems )
        self.ui.List1.list1SelectedItem.connect(self.fill_List2)
        ...

    def fill_List2(self):
        if self.genericThread.isRunning():
            self.genericThread.stop()
        self.ui.List2.clear()
        list1SelectedItem = str(self.ui.List1.currentItem().text())
        self.genericThread.start()