PySide2 Qthread 崩溃
Posted
技术标签:
【中文标题】PySide2 Qthread 崩溃【英文标题】:PySide2 Qthread crash 【发布时间】: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_())
【问题讨论】:
【参考方案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()
【讨论】:
我在我的回答中指出了同样的问题,并解释了问题的原因。以上是关于PySide2 Qthread 崩溃的主要内容,如果未能解决你的问题,请参考以下文章
也许 QThread 中的 QTLineEdit 范围会导致程序崩溃?