gpt4 book ai didi

Python 在 PyQt5 应用程序中因 2 个工作线程而崩溃

转载 作者:太空宇宙 更新时间:2023-11-04 02:53:08 24 4
gpt4 key购买 nike

我想在我的应用程序中有 2 个工作线程。一个应该在 GUI 加载后立即开始运行,另一个应该稍后通过某个信号启动。假设这是一个按钮点击。

当我的 Python 解释器在执行第二个线程时崩溃(如显示 Windows 错误“Python 停止工作”,没有堆栈跟踪)时,我遇到了一个奇怪的行为。

这是一个例子,当我点击按钮后它会立即崩溃。

class Worker(QtCore.QThread):
def __init__(self, method_to_run):
super().__init__()
self.method = method_to_run

def run(self):
self.method()

class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
self.button = QPushButton('Test', self)
self.label = QLabel(self)
self.button.clicked.connect(self.handleButton)
layout = QVBoxLayout(self)
layout.addWidget(self.label)
layout.addWidget(self.button)
self.worker = Worker(self.test_method)
self.worker.start()

def handleButton(self):
self.label.setText('Button Clicked!')
worker = Worker(self.test_method)
worker.start()

@staticmethod
def test_method():
res = [i*i for i in range(100500)]

if __name__ == '__main__':

import sys
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())

更奇怪的是,当您出于某种原因调试应用程序时它不会崩溃。

我在这里错过了什么?

编辑我可以从故障转储中得到很多,因为我没有 QT 的符号。但看起来崩溃发生在 QtCore.dll 内部

ExceptionAddress: 00000000632d4669 (Qt5Core!QThread::start+0x0000000000000229)

最佳答案

问题是您没有保存对线程的引用,所以它在您退出 handleButton 后立即被删除。如果您保存一个引用,就会引出如何处理其生命周期的问题。

QThread 不仅仅是系统线程的包装器 - 它实现了其他服务,让您可以将线程连接到 GUI。您可以使用其 finished 处理程序在小部件终止进行任何清理时向其发出信号。

在此示例中,我将工作程序保存为 self.worker2 并阻止第二次启动工作程序,直到第一个工作程序完成。

import PyQt5
import PyQt5.QtCore as QtCore
from PyQt5.QtWidgets import *
import time

class Worker(QtCore.QThread):
def __init__(self, method_to_run):
super(Worker, self).__init__()
self.method = method_to_run

def run(self):
self.method()

class Window(QWidget):
def __init__(self):
super().__init__()
self.button = QPushButton('Test', self)
self.label = QLabel(self)
self.button.clicked.connect(self.handleButton)
layout = QVBoxLayout(self)
layout.addWidget(self.label)
layout.addWidget(self.button)
self.worker = Worker(self.test_method)
self.worker.start()
self.worker2 = None

def handleButton(self):
self.label.setText('Button Clicked!')
# likely better to disable the button instead... but
# this shows events in action.
if self.worker2:
self.label.setText('Worker already running')
else:
self.worker2 = Worker(self.test_method)
self.worker2.finished.connect(self.handle_worker2_done)
self.worker2.start()

def handle_worker2_done(self):
self.worker2 = None
self.label.setText('Worker done')

@staticmethod
def test_method():
#res = [i*i for i in range(100500)]
time.sleep(3)

if __name__ == '__main__':

import sys
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())

关于Python 在 PyQt5 应用程序中因 2 个工作线程而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43188123/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com