0

I would like to start a Thread with PyQt, that performs some actions independently of the rest of the app. This includes running an external program. This may take some minutes.

My problem is that using QThread for this stops the whole app. When running this small program, clicking the button will freeze the app for 10 seconds.

What can I do to make QThread behave as a Thread. I know that I can add some timers and divide it into events, but that is not my idea of a thread.

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtCore import QThread

class ProgramThread(QThread):
    def __init__(self):
        QThread.__init__(self)

    def __del__(self):
        self.wait()

    def run(self):
        QThread.sleep(10)

class App(QWidget):
    def __init__(self):
        super().__init__()
        thread = QPushButton('Start Thread',self)
        thread.clicked.connect(self.startthread)
        thread.move(20,100)
        self.show()

    def startthread(self):
        t = ProgramThread()
        t.start()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())
1
  • Change t = ProgramThread() to self.t = ProgramThread() and t.start() to self.t.start() Commented Feb 12, 2019 at 22:46

1 Answer 1

1

QThread is not a thread, it is a thread handler. In your case the problem is that the variable t is local so it will be deleted after executing the start, at that moment the __del__ method is called, and this calls wait() that runs in the main thread blocking the GUI, this blocking It will be until the run method finishes executing, so in conclusion the problem is that t is a local variable, the solution is to keep it in time so there are 2 possibilities: 1) pass it to self as a parent or 2) make it a member of the class:

class ProgramThread(QThread):
    def run(self):
        QThread.sleep(10)

    def __del__(self):
        self.wait()

class App(QWidget):
    def __init__(self):
        super().__init__()
        thread = QPushButton('Start Thread',self)
        thread.clicked.connect(self.startthread)
        thread.move(20,100)
        self.show()

    def startthread(self):
        # method 1
        t = ProgramThread(self)
        t.start()
        # method 2
        # self.t = ProgramThread()
        # self.t.start()
Sign up to request clarification or add additional context in comments.

1 Comment

Thank You for clearing out this detail. It works like a charm now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.