Search code examples
pythonmultithreadingpyqt5qthread

How to quit PyQT QThread automatically when it is done?


I want a sound to play when I click a button in PyQT5.

Playing a sound appears to be a blocking operation, so GUI is unresponsive. Thus I want to start a new thread, play sound, and delete the thread, all in a non-blocking manner.

I create a thread class

class playSoundThread(QtCore.QThread):
    def __init__(self, soundpath):
        QtCore.QThread.__init__(self)
        self.soundpath = soundpath

    def __del__(self):
        self.wait()
        print("Thread exited")

    def run(self):
        playsound(self.soundpath)

And run it as follows

class MainClass(...):
    ...

    def playsound(self, soundKey):
        self.thisSoundThread = playSoundThread(self.sounds[soundKey])
        self.thisSoundThread.start()

Everything works fine and is non-blocking. The only problem is that the thread does not get deleted when the sound stops playing. I have tried calling del self.thisSoundThread, but this operation seems to be blocking, defeating the point.

What is the correct way to exit a thread after completion in a non-blocking way?


Solution

  • Why it should get deleted? I do not see any call of "del" and you assign it into instance so GC also doesnt because there is still existing reference.

    If you want to delete it you have to do something like this:

    class MainClass(...):
        ...
    
        def playsound(self, soundKey):
            self.thisSoundThread = playSoundThread(self.sounds[soundKey])
            self.thisSoundThread.finished.connect(self.threadfinished)
            self.thisSoundThread.start()
    
        def threadfinished(self)
            del self.thisSoundThread
            # or set it to None