Search code examples
pythonmultithreadingpyqtpyqt5qthread

PyQt5 QThread.self.setTerminationEnabled(False) seems not to work


borrowing from PySide QThread.terminate() causing fatal python error I tried this example:

from PyQt5 import QtCore, QtGui, QtWidgets


class Looper(QtCore.QThread):
    """QThread that prints natural numbers, one by one to stdout."""
    def __init__(self, *args, **kwargs):
        super(Looper, self).__init__(*args, **kwargs)
        # self.setTerminationEnabled(True)
        
        self.setTerminationEnabled(False)

    def run(self):
        i = 0
        while True:
            self.msleep(100)
            print(i)
            i += 1

# Initialize and start a looper.                                                                      
looper = Looper()

looper.setTerminationEnabled(False)
looper.start()

# Sleep main thread for 5 seconds.                                                                    
QtCore.QThread.sleep(3)

# Terminate looper.                                                                                   
looper.terminate()

app = QtWidgets.QApplication([])
app.exec_()

I could be wrong, but expected looper.setTerminationEnabled(False) or self.setTerminationEnabled(False) to prevent the QThread from terminate() according to https://doc.qt.io/qtforpython-6/PySide6/QtCore/QThread.html#PySide6.QtCore.PySide6.QtCore.QThread.setTerminationEnabled.

But to me it doesn't work. Any hint ??

I am using Qt: v 5.15.2 PyQt: v 5.15.7


Solution

  • setTerminationEnabled is a static method. It doesn't enable or disable termination of the thread it's called on, and in fact, you're not supposed to call it on a QThread instance at all.

    setTerminationEnabled enables or disables termination of the thread that calls setTerminationEnabled. You need to call it from the looper thread. And no, putting it in __init__ doesn't do that - __init__ is not executed by the new thread. That thread hasn't even started yet. You need to call it in run:

    def run(self):
        QTCore.QThread.setTerminationEnabled(False)
        ...