QThread:线程在 Python 中仍然是 运行 时被销毁
QThread: Destroyed while thread is still running in Python
我有这部分代码,它有时有效,有时会抛出警告:
QThread: Destroyed while thread is still running
这部分在UiMainWindow中class
obj_thread = QtCore.QThread()
def ok():
self.module_src_tree.setStyleSheet('background-color: #81F781')
obj_thread.quit()
def err():
self.module_src_tree.setStyleSheet('background-color: #F78181')
obj_thread.quit()
tmp = self.Temp(self, module_revision)
tmp.moveToThread(obj_thread)
tmp.finished.connect(ok)
tmp.error.connect(err)
obj_thread.started.connect(tmp.run)
obj_thread.start()
这是 class 在 UiMainWindow class
class Temp(QtCore.QObject):
finished = QtCore.pyqtSignal()
error = QtCore.pyqtSignal()
def __init__(self, gui, module_revision):
QtCore.QObject.__init__(self)
self.gui = gui
self.module_revision = module_revision
def run(self):
try:
self.gui.dp.pack_module_source(self.gui.module_src_show_list, self.gui.module_src_pack_list,
path=str(self.gui.path_box.text()), revision=self.module_revision)
self.finished.emit()
except Exception as e:
self.error.emit()
raise e
我想用这段代码做什么 - 我想在不冻结主应用程序的情况下压缩一些文件。所以我开始在后台工作的新线程。但是我需要这样的功能,即如果出现问题,Widget 在压缩完成后将其颜色更改为绿色或红色。
也许我做错了什么?也许不是这样?
我在更改颜色部分时遇到的大多数问题。
此致,
马立克
@three_pineapples,有时好像根本就没有开始。但是现在没有error/warning。
我已经修改了代码:
class UiMainWindow(object):
# thread pool
thread_pool = [None, None, None, None]
这是在 class 构造函数之前。 Temp class 与上面保持一致,Thread 调用部分代码现在看起来像这样:
self.thread_pool[3] = None
self.thread_pool[3] = QtCore.QThread()
def ok():
self.module_src_tree.setStyleSheet('background-color: #81F781')
self.thread_pool[3].quit()
def err():
self.module_src_tree.setStyleSheet('background-color: #F78181')
self.thread_pool[3].quit()
tmp = self.Temp(self, module_revision)
tmp.moveToThread(self.thread_pool[3])
tmp.finished.connect(ok)
tmp.error.connect(err)
self.thread_pool[3].started.connect(tmp.run)
self.thread_pool[3].start()
当线程被 Python 垃圾收集时会出现此问题。
您需要保存对 QThread
的引用,这样它就不会被垃圾回收。只要做 self.obj_thread = QtCore.QThread()
如果有可能同时存在多个 QThread
,并且您将引用存储在同一个变量中,那么您可能需要将对象存储在列表中。但是,当给定线程完成时,您需要从列表中清除对象(因此它们被垃圾收集),这样您就不会向应用程序引入内存泄漏。
我有这部分代码,它有时有效,有时会抛出警告:
QThread: Destroyed while thread is still running
这部分在UiMainWindow中class
obj_thread = QtCore.QThread()
def ok():
self.module_src_tree.setStyleSheet('background-color: #81F781')
obj_thread.quit()
def err():
self.module_src_tree.setStyleSheet('background-color: #F78181')
obj_thread.quit()
tmp = self.Temp(self, module_revision)
tmp.moveToThread(obj_thread)
tmp.finished.connect(ok)
tmp.error.connect(err)
obj_thread.started.connect(tmp.run)
obj_thread.start()
这是 class 在 UiMainWindow class
class Temp(QtCore.QObject):
finished = QtCore.pyqtSignal()
error = QtCore.pyqtSignal()
def __init__(self, gui, module_revision):
QtCore.QObject.__init__(self)
self.gui = gui
self.module_revision = module_revision
def run(self):
try:
self.gui.dp.pack_module_source(self.gui.module_src_show_list, self.gui.module_src_pack_list,
path=str(self.gui.path_box.text()), revision=self.module_revision)
self.finished.emit()
except Exception as e:
self.error.emit()
raise e
我想用这段代码做什么 - 我想在不冻结主应用程序的情况下压缩一些文件。所以我开始在后台工作的新线程。但是我需要这样的功能,即如果出现问题,Widget 在压缩完成后将其颜色更改为绿色或红色。
也许我做错了什么?也许不是这样?
我在更改颜色部分时遇到的大多数问题。
此致,
马立克
@three_pineapples,有时好像根本就没有开始。但是现在没有error/warning。
我已经修改了代码:
class UiMainWindow(object):
# thread pool
thread_pool = [None, None, None, None]
这是在 class 构造函数之前。 Temp class 与上面保持一致,Thread 调用部分代码现在看起来像这样:
self.thread_pool[3] = None
self.thread_pool[3] = QtCore.QThread()
def ok():
self.module_src_tree.setStyleSheet('background-color: #81F781')
self.thread_pool[3].quit()
def err():
self.module_src_tree.setStyleSheet('background-color: #F78181')
self.thread_pool[3].quit()
tmp = self.Temp(self, module_revision)
tmp.moveToThread(self.thread_pool[3])
tmp.finished.connect(ok)
tmp.error.connect(err)
self.thread_pool[3].started.connect(tmp.run)
self.thread_pool[3].start()
当线程被 Python 垃圾收集时会出现此问题。
您需要保存对 QThread
的引用,这样它就不会被垃圾回收。只要做 self.obj_thread = QtCore.QThread()
如果有可能同时存在多个 QThread
,并且您将引用存储在同一个变量中,那么您可能需要将对象存储在列表中。但是,当给定线程完成时,您需要从列表中清除对象(因此它们被垃圾收集),这样您就不会向应用程序引入内存泄漏。