【问题标题】:PySide2 Qthread crashPySide2 Qthread 崩溃
【发布时间】:2019-11-01 08:43:16
【问题描述】:

由于 Qtcore.Signal,我想使用 PySide2 Qtcore.Qthread,但我最终得到了这个错误: 进程以退出代码 -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_())

【问题讨论】:

    标签: python qthread pyside2


    【解决方案1】:

    说明

    如果您在 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”类属性
    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()
    

    【讨论】:

    • 我更新了问题,用你的方法我做了一个 QApplication 和小部件,但它又抛出了同样的错误!
    • @SaeidGholizade 如果我的回答对您有所帮助,请不要忘记标记为正确,如果您不知道该怎么做,请查看tour
    【解决方案2】:

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

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

    【讨论】:

    • 我在我的回答中指出了同样的问题,并解释了问题的原因。
    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 2023-01-30
    相关资源
    最近更新 更多