首页 > 解决方案 > PySide2 QThread 错误:QThread:在线程仍在运行时被销毁

问题描述

我是 PySide2 的新手。我只是想启动一个示例应用程序并在应用程序启动时启动一个线程,并希望在应用程序关闭时停止该线程。当我关闭应用程序时,我收到以下错误:QThread: Destroyed while the thread is still running。sample_ui.py 是我从 sample_ui.ui 转换而来的 python 文件

代码:

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

输出:

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

标签: qtpyqtpyqt5pyside2

解决方案


解释:

默认情况下,QThread run() 方法具有以下实现:

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

换句话说,run 方法执行一个事件循环,但是当覆盖该方法时,您将通过 while 循环删除事件循环。

另一方面,如果审查了 Qt 文档:

无效 QThread::quit()

告诉线程的事件循环以返回码 0(成功)退出。相当于调用 QThread::exit(0)。

如果线程没有事件循环,这个函数什么也不做

(强调我的)

因此,如果没有事件循环,那么 quit 方法将什么也不做。

解决方案:

一种可能的解决方案是使用isInterruptionRequested()andrequestInterruption()因为第一个指示标志的状态,而第二个更改该标志的状态。另一方面,您必须使用以下wait()方法等待线程完成执行:

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

推荐阅读