簡體   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