python - 'QThread : Destroyed while thread is still running' on quit

标签 python multithreading qt pyqt pyside

我正在尝试找到一种方法来正确退出我的应用程序。当我退出时,我收到一条错误消息: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_())

线程应该在退出时以某种方式终止吗?请注意,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_())

关于python - 'QThread : Destroyed while thread is still running' on quit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28714630/

相关文章:

c++ - 应用程序的自定义任务栏菜单

c++ - 在带有 CDB 的 Qt Creator 中将指针显示为数组以供调试器使用

c - 跨多个文件线程

.net - .NET 4.0中的Parallel.ForEach

python - 从 python 运行 MATLAB 脚本 + 传递参数

python - PySide: 'PySide.QtCore.Signal' 对象没有属性 'emit'

c# - "Double-Checked Locking is Broken"是仅限 Java 的东西吗?

c++ - 如何停止循环线程

python - 如何使用每小时的值对 pandas 系列进行重新采样

Python Tkinter,显示实时数据