PyQTPySide6:QThread: Destroyed while thread is still running,彻底解决

针对PyQT5和PySide6,在启动线程后,如果退出主线程,总是出现:QThread: Destroyed while thread is still running,这个提示意味着,在主线程退出后,程序中创建的子线程还在运行中,即无法彻底终止子线程。

目前网上有n多解决方案,但实际没有讲到点子上。我这里总结经验如下:退出时,必须停止创先子线程;!
1、主线程要显式调用子线程的析构函数__del__(),
2、线程的析构函数中,通过标志位方式,停止程序运行,即正常结束即可。

主程序中的,显示调用析构函数:

@Slot()
    def btn_close_clicked(self):
        self.thread.__del__()
        self.close()

在线程的析构函数中,设置标志位来控制任务循环体

QTheard的析构函数:

def __del__(self):
        print('Stop thread task running.')
        self.status = False
        self.wait()

QT heard的任务函数:

def run(self):
        print('Start a new thread task.')
        
        while self.status:            
            self.count += 1     
            self.s = f"已执行{self.count}秒"  
            self.sig.emit(self.s)
            time.sleep(1)

经测试后,点击“EXIT"按钮,正常调用析构函数后,不在提示。
但是,如果点击右上角”X“按钮,由于不能正常显式调用析构函数,依然还是有提示的。切记切记!

最后,验证的全部代码如下,供各位学习借鉴。

'''
@File    :   ex_Thread.py
@Time    :   2022/12/01 15:08:13
@Author  :   
@Version :   1.00.000
@Contact :   
@License :   (C)Copyright 2022, Info Analysis and Insight for Future Studios
@https   :   None
@Desc    :   None
'''

# here put the import lib
import sys
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
import time


class MainWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.initUi()
        self.conn()
        self.show()

    # init self
    def initUi(self):
        self.setWindowTitle('QThread example')
        self.resize(300, 200)

        layout = QVBoxLayout()

        self.label = QLabel('labeltext')
        self.btn = QPushButton('OK')
        self.btn_close =QPushButton('EXIT')
        # self.setCentralWidget(self.label)

        layout.addWidget(self.label, 0, Qt.AlignCenter)
        layout.addWidget(self.btn)
        layout.addWidget(self.btn_close)

        self.setLayout(layout)
        
        self.thread = Worker()

    def conn(self):         
        self.thread.sig.connect(self.updateLabel)        
        self.btn.clicked.connect(self.buttonClicked)
        self.btn_close.clicked.connect(self.btn_close_clicked)
    
    @Slot()
    def buttonClicked(self):
        
        self.thread.start()
    
    @Slot()
    def updateLabel(self, text):
        self.label.setText(text)

    @Slot()
    def btn_close_clicked(self):
        self.thread.__del__()
        self.close()

class Worker(QThread):
    sig = Signal(str)
    
    def __init__(self, parent=None):
        print('Created a new thread of Worker')
        super(Worker, self).__init__(parent)
        self.status = True
        self.count = 0

    def __del__(self):
        print('Stop thread task running.')
        self.status = False
        self.wait()
    
    def run(self):
        print('Start a new thread task.')
        
        while self.status:            
            self.count += 1     
            self.s = f"已执行{self.count}秒"  
            self.sig.emit(self.s)
            time.sleep(1)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    app.exec()

你可能感兴趣的:(PySide6,PyQT5,python)