PyQt的的QThread:被毁坏,而线程仍在运行
问题描述:
尽管保存到QThread
作为self.lightsThread
参考,停止QObject
self.lightsWorker
然后开始self.lightsThread
再次引起错误PyQt的的QThread:被毁坏,而线程仍在运行
QThread: Destroyed while thread is still running
停止self.lightsWorker
后,必须在QThread
self.lightsThread
停止太?如果不是,那么问题似乎是什么?
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import time
class Screen(QMainWindow):
def __init__(self):
super(Screen, self).__init__()
self.initUI()
def initUI(self):
self.lightsBtn = QPushButton('Turn On')
self.lightsBtn.setCheckable(True)
self.lightsBtn.setStyleSheet("QPushButton:checked {color: white; background-color: green;}")
self.lightsBtn.clicked.connect(self.lightsBtnHandler)
self.setCentralWidget(self.lightsBtn)
def lightsBtnHandler(self):
if self.lightsBtn.isChecked():
self.startLightsThread()
else:
self.stopLightsThread()
def startLightsThread(self):
print 'start lightsThread'
self.lightsThread = QThread()
self.lightsWorker = LightsWorker()
self.lightsWorker.moveToThread(self.lightsThread)
self.lightsThread.started.connect(self.lightsWorker.work)
self.lightsThread.start()
def stopLightsThread(self):
print 'stop lightsThread'
self.lightsWorker.stop()
class LightsWorker(QObject):
signalFinished = pyqtSignal()
def __init__(self):
QObject.__init__(self)
self._mutex = QMutex()
self._running = True
@pyqtSlot()
def work(self):
while self._running:
print 'working'
time.sleep(1)
self.signalFinished.emit()
@pyqtSlot()
def stop(self):
print 'Stopping'
self._mutex.lock()
self._running = False
self._mutex.unlock()
app = QApplication(sys.argv)
window = Screen()
window.show()
sys.exit(app.exec_())
答
以下答案https://stackoverflow.com/a/32138213/7742341停止lightWorker
你应该后从线程退出并等待,直到它停止
def stopLightsThread(self):
print('stop lightsThread')
self.lightsWorker.stop()
self.lightsThread.quit()
self.lightsThread.wait()
答
我不得不面对C++相同的问题,但问题是相同的。
问题是,当关联的线程仍在运行时,您的QThread实例被删除。这可能是非常危险的,因为线程代码的执行会被中断,并保证线程已准备好被删除。
例如:
- 一个线程控制
- 一个的ressource在该对象的析构释放(显式或使用的QObject母体时implicilty喜欢的对象(工人)的执行,并且寿命时间/子系统)
- 由于线程执行被中断时,该对象将不被删除
它导致内存泄漏和的ressource泄漏。
在你的代码中,worker停止了,但不是工作线程。我不是蟒蛇专家,但它似乎也是你的工人对象已停止但未被删除。
,正确停止工作者和线程,你应该:
- 将消息发送给你的工人告诉它“停止工作”
- 问你的线程退出:它会发布一个“退出“消息将在工人执行
- 等待之后处理您的线程的线程停止
的最后一步是optionnal:如果线程和工人不同意蒙山ressources其他的对象,你可能不需要等待他们完成,只是忘记他们。
唯一的解决方法是在退出应用程序之前应正确停止所有线程:在应用程序退出之前,应等待当前所有正在运行的线程停止。
对于简单的任务,您还应该考虑使用QtConcurrent框架。
我的应用程序有同样的问题。然而,这不是真的错误,一切似乎都在起作用。 – Matho