簡體   English   中英

退出時“ QThread:線程仍在運行時被銷毀”

[英]'QThread: Destroyed while thread is still running' on quit

我正在嘗試找到一種方法來正確退出我的應用程序。 退出時,出現錯誤消息QThread: Destroyed while thread is still running 我有一個用於將輸出饋給QTextBrowser的線程。 退出的正確方法應該是什么? 這是我得到的:

class LogReceiver(QtCore.QObject):
    mysignal = QtCore.Signal(str)

    def __init__(self, queue, *args, **kwargs):
        QtCore.QObject.__init__(self, *args, **kwargs)
        self.queue = queue

    def run(self):
        while True:
            text = self.queue.get()
            self.mysignal.emit(text)

if __name__ == '__main__':
    queue = Queue()
    thread = QtCore.QThread()
    my_receiver = MyReceiver(queue)

    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()

    my_receiver.mysignal.connect(window.append_text)
    my_receiver.moveToThread(thread)
    thread.started.connect(my_receiver.run)
    thread.start()

    sys.exit(app.exec_())

thread是否應該在退出時終止? 請注意, self.queue.get()阻止並等待文本。

謝謝

您需要重新構造while循環,以使其不會無條件地阻塞。

您可以使用簡單的標志和超時來執行此操作:

    def run(self):
        self.active = True
        while self.active:
            try:
                text = self.queue.get(timeout=1.0)
                self.mysignal.emit(text)
            except Empty:
                continue

因此,現在隊列將不會無限期地阻塞,並且將每秒檢查一次標志以查看是否應退出循環。

編輯

這是一個基於您的代碼的工作示例:

import sys
from queue import Queue, Empty
from PySide import QtCore, QtGui

class LogReceiver(QtCore.QObject):
    mysignal = QtCore.Signal(str)

    def __init__(self, queue, *args, **kwargs):
        QtCore.QObject.__init__(self, *args, **kwargs)
        self.queue = queue

    def run(self):
        self.active = True
        while self.active:
            try:
                text = self.queue.get(timeout=1.0)
                self.mysignal.emit('text')
            except Empty:
                continue
        print('finished')

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.queue = Queue()
        self.thread = QtCore.QThread(self)
        self.receiver = LogReceiver(self.queue)
        self.receiver.moveToThread(self.thread)
        self.thread.started.connect(self.receiver.run)
        self.thread.start()

    def closeEvent(self, event):
        print('close')
        self.receiver.active = False
        self.thread.quit()
        self.thread.wait()

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.show()

    sys.exit(app.exec_())

嘗試:

# previous code here
thread.start()
app.exec_()

thread.terminate()
thread.wait()
sys.exit(0)

基本上,當exec_()完成時(例如,通過關閉窗口關閉QApplication ),您可以強制thread終止並wait() thread進行清理。 如果您的線程具有事件循環,則可以調用quit()而不是terminate() terminate()是通常不是一個好主意看: 在這里

更理想的方法是在run()方法ex中放置一個標志。

while !flag:
    do stuff

並將main更改為:

app.exec_()
flag = True
thread.wait()
sys.exit(0)

其中flag是全局變量。 run()方法完成時, QThread自行終止。

暫無
暫無

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

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