簡體   English   中英

QThread:在線程仍在運行時被銷毀:如何正確使用 QThreads 和 QTimers?

[英]QThread: Destroyed while thread is still running: How to proper use QThreads with QTimers?

我在理解以下測試代碼中發生了什么有點麻煩。

我創建了一個將進入線程的計時器。 該線程可以在對象內停止,但是當部署在主 QT 應用程序中時,該線程會在主應用程序結束時以某種方式獲得垃圾收集。

問:如何在主應用程序結束之前正確停止QThread。(或者以更好的方式實現線程?)

import sys

from PySide6.QtCore import QTimer, Qt, QThread
from PySide6.QtWidgets import QWidget, QApplication, QLabel, QHBoxLayout

class Counter(QWidget):
    def __init__(self):
        super().__init__()

        self.cnt = 0

        self.timer = QTimer()
        self.timer.timeout.connect(self.__update_by_timer)

        self.label = QLabel()
        self.label.setText(str(self.cnt))

        self._layout = QHBoxLayout()
        self._layout.addWidget(self.label,  Qt.AlignCenter)
        self.setLayout(self._layout)

        self.timer.start(1000)
        self.thread = QThread()
        self.timer.moveToThread(self.thread)
        self.thread.start(QThread.Priority.LowestPriority)


    def __del__(self):
        self.thread.exit()

    def __update_by_timer(self):
        self.cnt += 1
        self.label.setText(str(self.cnt))

if __name__ == "__main__":

    app = QApplication(sys.argv)
    cnt = Counter()
    cnt.show()
    sys.exit(app.exec())

主應用截圖:

在此處輸入圖像描述

我找到了我的問題的答案,

問題:如果您單擊應用程序窗口,將不會調用“計數器”對象的析構函數,因此線程中的計時器與 GUI 應用程序有些距離。

為了克服這個問題,我包含了一個析構函數,它停止計時器並關閉線程。 這必須由必須從 QWidget 類派生的“closeEvent”方法調用。

def __del__(self):
    self.timer.stop()
    self.thread.quit()

def closeEvent(self, event: QCloseEvent) -> None:
    ''' Derived method from QWidget '''
    self.__del__()
    super().closeEvent(event)

原始代碼中的一個額外警告是計時器本身。 這必須先采用父級的“計數器”類,然后才能在析構函數中停止。

    self.timer = QTimer(self)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM