简体   繁体   English

退出时“ QThread:线程仍在运行时被销毁”

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

I'm trying to find a way to quit my app properly. 我正在尝试找到一种方法来正确退出我的应用程序。 When I exit, I get an error saying QThread: Destroyed while thread is still running . 退出时,出现错误消息QThread: Destroyed while thread is still running I have a thread for feeding output to a QTextBrowser . 我有一个用于将输出馈给QTextBrowser的线程。 What should be the proper way to exit? 退出的正确方法应该是什么? Here's what I've got: 这是我得到的:

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

Should thread somehow be terminated upon exit? thread是否应该在退出时终止? Note that self.queue.get() blocks and waits for text. 请注意, self.queue.get()阻止并等待文本。

Thanks 谢谢

You need to re-structure the while loop so that it doesn't block uncondtionally. 您需要重新构造while循环,以使其不会无条件地阻塞。

You can do this with a simple flag and a timeout: 您可以使用简单的标志和超时来执行此操作:

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

So now the queue won't block indefinitely, and the flag will be checked once a second to see if the loop should be exited. 因此,现在队列将不会无限期地阻塞,并且将每秒检查一次标志以查看是否应退出循环。

EDIT : 编辑

Here's a working example based on your code: 这是一个基于您的代码的工作示例:

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

Try: 尝试:

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

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

Basically when exec_() finishes ( QApplication is closed ex. by closing the window) you force the thread to terminate and wait() for it to cleanup. 基本上,当exec_()完成时(例如,通过关闭窗口关闭QApplication ),您可以强制thread终止并wait() thread进行清理。 If your thread has an event loop you can call quit() instead of terminate() . 如果您的线程具有事件循环,则可以调用quit()而不是terminate() terminate() is generally not a good idea see: here . terminate()是通常不是一个好主意看: 在这里

The more desirable approach would be to put a flag in run() method ex. 更理想的方法是在run()方法ex中放置一个标志。

while !flag:
    do stuff

and change main to: 并将main更改为:

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

Where flag is a global variable. 其中flag是全局变量。 QThread terminates itself when run() method finishes. run()方法完成时, QThread自行终止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 PyQt QThread:在线程仍在运行时被销毁 - PyQt QThread: Destroyed while thread is still running QThread:当线程仍在Python中运行时被破坏 - QThread: Destroyed while thread is still running in Python QThread:在线程仍在运行时被销毁 - QThread: Destroyed while thread is still running PyQt5 - QThread:线程仍在运行时被销毁 - PyQt5 - QThread: Destroyed while thread is still running “QThread:当线程仍在运行时被破坏”从Windows cmd或IDLE运行但不是从PyCharm运行? - “QThread: Destroyed while thread is still running” when run from the Windows cmd or IDLE but not from PyCharm? PYQt5:QThread:线程仍在运行时销毁(实例分配为 QDialog ) - PYQt5: QThread: Destroyed while thread is still running ( with instance assigned as QDialog ) QThread:在线程仍在运行时被销毁:如何正确使用 QThreads 和 QTimers? - QThread: Destroyed while thread is still running: How to proper use QThreads with QTimers? 使用Python的QtWebkit呈现基于Javascript的页面,获取QThread:在线程仍在运行时被销毁 - Using Python's QtWebkit to render Javascript-based page, get QThread: Destroyed while thread is still running PyQt5:在线程仍在运行时销毁 - PyQt5 : Destroyed while thread is still running PyQt错误“QProcess:进程仍在运行时被销毁” - PyQt error “QProcess: Destroyed while process is still running”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM