'QThread: Destroyed while thread is still running' 退出
'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()
会阻塞并等待文本。
谢谢
尝试:
# previous code here
thread.start()
app.exec_()
thread.terminate()
thread.wait()
sys.exit(0)
基本上当 exec_()
完成时(QApplication
关闭,例如通过关闭 window)你强制 thread
终止并 wait()
它清理。如果你的线程有一个事件循环,你可以调用 quit()
而不是 terminate()
。 terminate()
通常不是一个好主意,请参阅:here。
更理想的方法是在 run()
方法 ex.
中放置一个标志
while !flag:
do stuff
并将 main 更改为:
app.exec_()
flag = True
thread.wait()
sys.exit(0)
其中flag
是一个全局变量。 QThread
在 run()
方法完成时自行终止。
您需要重新构建 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_())
我正在尝试找到一种正确退出我的应用程序的方法。当我退出时,我收到一条错误消息 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()
会阻塞并等待文本。
谢谢
尝试:
# previous code here
thread.start()
app.exec_()
thread.terminate()
thread.wait()
sys.exit(0)
基本上当 exec_()
完成时(QApplication
关闭,例如通过关闭 window)你强制 thread
终止并 wait()
它清理。如果你的线程有一个事件循环,你可以调用 quit()
而不是 terminate()
。 terminate()
通常不是一个好主意,请参阅:here。
更理想的方法是在 run()
方法 ex.
while !flag:
do stuff
并将 main 更改为:
app.exec_()
flag = True
thread.wait()
sys.exit(0)
其中flag
是一个全局变量。 QThread
在 run()
方法完成时自行终止。
您需要重新构建 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_())