0

I'm developing a QT app using QT for Python (Pyside). I'm trying to update the GUI async using signals and slots. The long running process should run on a separate thread. In this example, I've created a Worker thread and a QThread to run the worker into it.

But when launching the thread, it generates a core dump error and the app suddenly closes.

As a side note, the error does not happens when the thread and the worker are created as self.thread and self.worker

Why is this happening? Why the error disappears when using the self. namespace?

import sys
import time
import random
from PySide6 import QtCore, QtWidgets, QtGui


class WaitTimerWorker(QtCore.QObject):
    finished = QtCore.Signal(int)

    def __init__(self, time_in_seconds):
        super(WaitTimerWorker, self).__init__(parent=None)
        self.time_in_seconds = time_in_seconds

    def run(self):
        time.sleep(self.time_in_seconds)
        self.finished.emit(self.time_in_seconds)

class MyWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"]

        self.button = QtWidgets.QPushButton("Click me!")
        self.text = QtWidgets.QLabel("Hello World",
                                     alignment=QtCore.Qt.AlignCenter)

        self.layout = QtWidgets.QVBoxLayout(self)
        self.layout.addWidget(self.text)
        self.layout.addWidget(self.button)

        self.button.clicked.connect(self.button_is_clicked)

    def magic(self, time):
        self.text.setText("{}, after {} seconds".format(random.choice(self.hello), time))

    def button_is_clicked(self):
        # Creating the thread and worker in local space generates a core dump
        thread = QtCore.QThread()
        worker = WaitTimerWorker(3)

        # Creating the thread and worker in self. does not generate a core dump
        # self.thread = QtCore.QThread()
        # self.worker = WaitTimerWorker(3)
        # thread = self.thread
        # worker = self.worker

        worker.moveToThread(thread)

        thread.started.connect(worker.run)
        worker.finished.connect(thread.quit)
        worker.finished.connect(worker.deleteLater)
        thread.finished.connect(thread.deleteLater)
        worker.finished.connect(self.magic)

        thread.start()

if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    widget = MyWidget()
    widget.resize(300, 200)
    widget.show()

    sys.exit(app.exec())
eyllanesc
  • 221,139
  • 17
  • 121
  • 189
fernandezr
  • 595
  • 6
  • 18
  • 1
    You must keep references to the thread and worker, otherwise they will be garbage-collected after `button_is_clicked` returns. – ekhumoro Oct 18 '21 at 16:09

0 Answers0