PySide2 QThread Error: QThread: Destroyed while thread is still running

旧街凉风 提交于 2021-02-07 10:07:21

问题


I am new to PySide2. I am just trying to launch a sample application and start a thread as the application starts and want to stop the thread as the application closes. When I am closing the application I am getting the following error: QThread: Destroyed while the thread is still running. The sample_ui.py is a python file that I converted from sample_ui.ui

Code:

import time
import sys
import sample_ui
from PySide2 import QtWidgets
from PySide2 import QtCore


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        main_window_ui = sample_ui.Ui_MainWindow()
        main_window_ui.setupUi(self)
        self.custom_thread = CustomThread()
        self.custom_thread.start()

    def closeEvent(self, event):
        self.custom_thread.stop()
        QtWidgets.QMainWindow.closeEvent(self, event)

class CustomThread(QtCore.QThread):
    def __init__(self):
        super(CustomThread, self).__init__()
    def run(self):
        while self.isRunning():
           print("Thread is Running")
           time.sleep(1)
    def stop(self):
        print("Thread Stopped")
        self.quit()




if __name__ == '__main__':
    app = QtWidgets.QApplication()
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

Output:

Thread is Running
Thread is Running
Thread is Running
Thread Stopped
QThread: Destroyed while thread is still running


回答1:


Explanation:

By default the QThread run() method has the following implementation:

// https://github.com/qt/qtbase/blob/5.14.1/src/corelib/thread/qthread.cpp#L601
void QThread::run()
{
    (void) exec();
}

In other words, the run method executes an event loop but when override that method you are removing the event loop by the while loop.

On the other hand if the Qt docs is reviewed:

void QThread::quit()

Tells the thread's event loop to exit with return code 0 (success). Equivalent to calling QThread::exit(0).

This function does nothing if the thread does not have an event loop.

(emphasis mine)

So if there is no event loop then the quit method will do nothing.

Solution:

A possible solution is to use isInterruptionRequested() and requestInterruption() since the first one indicates the state of the flag and the second one changes the state of that flag. On the other hand you have to wait for the thread to finish executing using the wait() method:

class CustomThread(QtCore.QThread):
    def run(self):
        while not self.isInterruptionRequested():
            print("Thread is Running")
            time.sleep(1)

    def stop(self):
        print("Thread Stopped")
        self.requestInterruption()
        self.wait()



回答2:


QThread::quit() does nothing if your thread doesn't have an event loop. You should use a flag that "turns off" the while inside your run() instead of checking what QThread::isRunning() returns. In addition it is advisable to always add a QThread::wait() with a specific time limit and then add (as a backup plan) a QThread::terminate().

Just as an experiment add a check for QThread::isRunning() after you call your stop() function and see what it returns.



来源:https://stackoverflow.com/questions/60124633/pyside2-qthread-error-qthread-destroyed-while-thread-is-still-running

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!