繁体   English   中英

PySide2 Qthread 崩溃

[英]PySide2 Qthread crash

由于Qtcore.Signal,我想使用PySide2 Qtcore.Qthread,但最终出现此错误: 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()

期望有这些打印,但我有这个错误:

进程以退出代码 -1073740791 结束

更新:

那么,为什么这段代码也会抛出同样的错误呢?

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_())

解释

如果您在 CMD/终端中运行代码,您将收到以下错误:

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

错误是因为线程在运行时被销毁,因为它是一个局部变量,另一方面 QThread 需要一个事件循环来运行

解决方案

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_())

更新:

“t”是一个局部变量,在执行 clicked 后将被消除,导致与初始代码相同的问题,解决方案是防止它立即被破坏,为此有 2 个选项:

  • 创建一个“t”class 属性
def clicked(self):
    self.t = Thread()
    self.t.done.connect(self.done)
    self.t.start()
  • 将 QThread 存放在生命周期较长的容器中:
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)

    # ...
  • 将其作为父级传递给“self”,但为此线程必须允许接收,因此您必须在构造函数中实现它:
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()

我找到了解决方案,但我不知道为什么要这样做。 线程应该是 class 的一部分。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM