简体   繁体   English

PyQt QThread:在线程仍在运行时被销毁

[英]PyQt QThread: Destroyed while thread is still running

Despite saving a reference to the QThread as self.lightsThread , stopping the QObject self.lightsWorker then starting self.lightsThread again caused the error 尽管将对QThread的引用保存为self.lightsThread ,但是停止QObject self.lightsWorker然后再次启动self.lightsThread导致错误

QThread: Destroyed while thread is still running

After stopping self.lightsWorker , must the QThread self.lightsThread be stopped too? 停止self.lightsWorkerQThread self.lightsThread必须停止吗? If not, what seems to be the problem? 如果不是,那似乎是什么问题?

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_())

following the answer https://stackoverflow.com/a/32138213/7742341 after stopping lightWorker you should to quit from the thread and wait untill it is stopped 停止lightWorker你应该退出https://stackoverflow.com/a/32138213/7742341 ,你应该从线程退出并等待直到它停止

def stopLightsThread(self):
    print('stop lightsThread')
    self.lightsWorker.stop()
    self.lightsThread.quit()
    self.lightsThread.wait()

I had to face the same issue in C++, but the problem is the same. 我不得不在C ++中遇到同样的问题,但问题是一样的。

The problem is that your QThread instance is deleted while the associated thread is still running. 问题是在关联的线程仍在运行时删除了QThread实例。 This can be really dangerous because the thread code execution is interrupted whitout any guarantee that the thread is ready to be deleted. 这可能非常危险,因为线程代码执行被中断,而且保证线程已准备好被删除。

For example : 例如 :

  • a thread control the execution and life time of an object (a worker) 线程控制对象(工人)的执行和生命时间
  • a ressource is released in this object destructor (explicity or implicilty like when using QObject parent/child system) 在这个对象析构函数中释放一个ressource(像使用QObject父/子系统时那样明显或隐含)
  • since the thread execution is interrupted, the object will not be deleted 由于线程执行被中断,因此不会删除该对象

It lead to a memory leak and a ressource leak. 它导致内存泄漏和资源泄漏。

In your code, the worker is stopped, but not the working thread. 在您的代码中,工作程序已停止,但不是工作线程。 I'm not python expert, but it also seems that your worker object is stopped but not deleted. 我不是python专家,但似乎你的worker对象已经停止但没有被删除。

To properly stop your worker and thread, you should : 要正确停止您的工作者和线程,您应该:

  • send a message to your worker to tell it to "stop working" 发消息给你的工人告诉它“停止工作”
  • ask your thread to quit : it will post an "exit" message to the thread that will be processed after the worker execution 请求您的线程退出:它会向工作执行后将处理的线程发送“退出”消息
  • wait for your thread to stop 等待你的线程停止

The last step is optionnal : if the thread and worker does not share ressources whith other object, you probably don't need to wait them to finish, just forget about them. 最后一步是optionnal:如果线程和worker没有与其他对象共享资源,你可能不需要等待它们完成,只需忘记它们。

The only execption is that all your thread should be properly stopped before exiting the application : you should wait for all current running threads to stop before application exit. 唯一的例外是在退出应用程序之前应该正确停止所有线程:您应该等待所有当前运行的线程在应用程序退出之前停止。

For simple tasks, you should also consider using QtConcurrent framework. 对于简单的任务,您还应该考虑使用QtConcurrent框架。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 PyQt5 - QThread:线程仍在运行时被销毁 - PyQt5 - QThread: Destroyed while thread is still running QThread:当线程仍在Python中运行时被破坏 - QThread: Destroyed while thread is still running in Python 退出时“ QThread:线程仍在运行时被销毁” - 'QThread: Destroyed while thread is still running' on quit QThread:在线程仍在运行时被销毁 - QThread: Destroyed while thread is still running PYQt5:QThread:线程仍在运行时销毁(实例分配为 QDialog ) - PYQt5: QThread: Destroyed while thread is still running ( with instance assigned as QDialog ) PyQt5:在线程仍在运行时销毁 - PyQt5 : Destroyed while thread is still running “QThread:当线程仍在运行时被破坏”从Windows cmd或IDLE运行但不是从PyCharm运行? - “QThread: Destroyed while thread is still running” when run from the Windows cmd or IDLE but not from PyCharm? QThread:在线程仍在运行时被销毁:如何正确使用 QThreads 和 QTimers? - QThread: Destroyed while thread is still running: How to proper use QThreads with QTimers? 使用Python的QtWebkit呈现基于Javascript的页面,获取QThread:在线程仍在运行时被销毁 - Using Python's QtWebkit to render Javascript-based page, get QThread: Destroyed while thread is still running PyQt错误“QProcess:进程仍在运行时被销毁” - PyQt error “QProcess: Destroyed while process is still running”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM