因此,我正在使用PySide2编写应用程序,该应用程序会将所有内容从stdout
重定向到中间queue.Queue
。 Queue
发出一个信号,该信号将由QThread处理,并将队列中的所有字符串附加到QTextEdit。
我已经环顾了四周,但不幸的是,似乎没有什么真正适合我。
那是我指的代码。
from PySide2 import QtWidgets, QtGui, QtCore
import sys
from queue import Queue
class WriteStream(object):
""" Redirects sys.stdout to a thread-safe Queue
Arguments:
object {object} -- base class
"""
def __init__(self, queue):
self.queue = queue
def write(self, msg):
self.queue.put(msg)
def flush(self):
""" Passing to create non-blocking stream (?!)
https://docs.python.org/3/library/io.html#io.IOBase.flush
"""
pass
class WriteStreamThread(QtCore.QThread):
queue_updated = QtCore.Signal(str)
def __init__(self, queue):
super(WriteStreamThread, self).__init__()
self.stop = False
self.queue = queue
def set_stop(self):
self.stop = True
self.wait() # waits till finished signal has been emitted
def run(self):
while not self.stop: # i guess this is blocking
msg = self.queue.get()
self.queue_updated.emit(msg)
self.sleep(1) # if commented out, app crashes
self.finished.emit()
class Verifyr(QtWidgets.QMainWindow):
def __init__(self, queue, parent=None):
super(Verifyr, self).__init__(parent)
self.centralwidget = QtWidgets.QWidget(self)
layout = QtWidgets.QVBoxLayout(self.centralwidget)
self.textedit = QtWidgets.QTextEdit(self)
layout.addWidget(self.textedit)
self.setLayout(layout)
self.setCentralWidget(self.centralwidget)
print("Verifyr initialised...")
self.listener_thread = WriteStreamThread(queue)
self.listener_thread.queue_updated.connect(self._log_to_qtextedit)
self.listener_thread.start()
@QtCore.Slot(str)
def _log_to_qtextedit(self, msg):
self.textedit.insertPlainText(msg)
if __name__ == '__main__':
# create Queue to be passed to WriteStream and WriteStreamListener
queue = Queue()
# redirect stdout to WriteStream()
sys.stdout = WriteStream(queue)
print("Redirected sys.stdout to WriteStream")
# launching the app
app = QtWidgets.QApplication(sys.argv)
window = Verifyr(queue)
app.aboutToQuit.connect(window.listener_thread.set_stop)
window.show()
sys.exit(app.exec_())
在WriteStreamThread
中,我使用一个while
循环,该循环不断发出信号,并被主应用程序捕获以附加到其QTextEdit。当我注释掉self.sleep(1)
时,应用程序将陷入无限循环。如果没有,则该线程将退出。
有人可以向我解释一下吗?
更新:
就像我在评论中提到的那样,我已经找到了错误...这是run()
的更新的WriteStreamThread
方法:
def run(self):
while not self.stop:
try:
msg = self.queue.get(block=False) # nasty little kwarg
except:
msg = "No items in queue. Sleeping 1sec.."
self.sleep(1)
self.queue_updated.emit(msg)
self.finished.emit() # optional
答案 0 :(得分:1)
我发现了错误。 queue.get()
的{{1}}方法中的run()
被阻止了。
将其更改为WriteStreamThread
并用try / catch包围即可完成工作。
愚蠢的我...