PySide2 Qthread crash

╄→尐↘猪︶ㄣ 提交于 2020-01-24 17:55:12

问题


I want to use PySide2 Qtcore.Qthread because of Qtcore.Signal, but I end up with this error: Process finished with exit code -1073740791

from PySide2.QtCore import QThread


class Thread(QThread):
    def run(self):
        print('task started')
        k = 0
        for i in range(10000):
            for j in range(5000):
                k += 1
        print('task finished')

Thread().start()

expect to have those prints but I have this error:

Process finished with exit code -1073740791

Update:

so, why this code also throw the same error?

class Thread(QThread):
    done = Signal()

    def __init__(self):
        super(Thread, self).__init__()

    def run(self):
        print('task started')
        k = 0
        for i in range(10000):
            for j in range(5000):
                k += 1
        print('task finished')
        self.done.emit()

class Widget(QtWidgets.QWidget):
    def __init__(self):
        super(Widget, self).__init__()
        btn = QtWidgets.QPushButton('test', parent=self)
        btn.clicked.connect(self.clicked)
        btn.show()

    def clicked(self):
        t = Thread()
        t.done.connect(self.done)
        t.start()

    def done(self):
        print('done')

app = QtWidgets.QApplication()
window = Widget()
window.show()
sys.exit(app.exec_())

回答1:


Explanation

If you run your code in a CMD/Terminal you will get the following error:

QThread: Destroyed while thread is still running
Aborted (core dumped)

And the error is caused because the thread is destroyed while it is still running since it is a local variable, on the other hand QThread needs an event loop to run

Solution

import sys
from PySide2.QtCore import QCoreApplication, QThread


class Thread(QThread):
    def run(self):
        print("task started")
        k = 0
        for i in range(10000):
            for j in range(5000):
                k += 1
        print("task finished")


if __name__ == "__main__":
    # create event loop
    app = QCoreApplication(sys.argv)

    th = Thread()
    th.start()

    th.finished.connect(QCoreApplication.quit)
    sys.exit(app.exec_())

Update:

"t" is a local variable that will be eliminated after executing clicked causing the same problem as your initial code, the solution is to prevent it from being destroyed instantly and for this there are 2 options:

  • Make a "t" class attribute
def clicked(self):
    self.t = Thread()
    self.t.done.connect(self.done)
    self.t.start()
  • Store the QThread in a container that has a longer life cycle:
class Widget(QtWidgets.QWidget):
    def __init__(self):
        super(Widget, self).__init__()
        btn = QtWidgets.QPushButton('test', parent=self)
        btn.clicked.connect(self.clicked)

        self.container = []

    def clicked(self):
        t = Thread()
        t.done.connect(self.done)
        t.start()
        self.container.append(t)

    # ...
  • Pass it as a parent to "self" but for this it is necessary that Thread allow to receive so you must implement that in the constructor:
class Thread(QThread):
    done = Signal()

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

    # ...
def clicked(self):
    t = Thread(self)
    t.done.connect(self.done)
    t.start()



回答2:


I found the solution but I don't know why I should do this. the thread should a part of the class.

self.t = Thread()
self.t.done.connect(self.done)
self.t.start()


来源:https://stackoverflow.com/questions/58656311/pyside2-qthread-crash

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!