У меня есть PyQt GUI с окном QTextEdit
, которое отображает операторы печати во время выполнения кода.Я решил сделать это, перенаправив sys.stdout
, следующие сообщения, подобные этой:
Распечатывать вывод консоли Python в Qtextedit
Это прекрасно работает для регистрации операторов печати, такчто пользователь может видеть, что произошло во время выполнения, однако я хотел бы, чтобы он обновлялся во время выполнения кода, а не записывал в буфер и распечатывал все в конце.Например, в этом коде нажатие кнопки «Выполнить» будет ждать 5 секунд, чтобы напечатать «Выполнено ...» и «Готово».после запуска функции, в то время как я хотел бы, чтобы она отображала «Выполняется ...», подождите 5 секунд, затем отобразите «Готово».
Вот основные принципы кода, который я написал:
import sys
import time
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication, QTextEdit
from PyQt5 import QtCore, QtGui
class Stream(QtCore.QObject):
"""Redirects console output to text widget."""
newText = QtCore.pyqtSignal(str)
def write(self, text):
self.newText.emit(str(text))
class GenMast(QMainWindow):
"""Main application window."""
def __init__(self):
super().__init__()
self.initUI()
# Custom output stream.
sys.stdout = Stream(newText=self.onUpdateText)
def onUpdateText(self, text):
"""Write console output to text widget."""
cursor = self.process.textCursor()
cursor.movePosition(QtGui.QTextCursor.End)
cursor.insertText(text)
self.process.setTextCursor(cursor)
self.process.ensureCursorVisible()
def closeEvent(self, event):
"""Shuts down application on close."""
# Return stdout to defaults.
sys.stdout = sys.__stdout__
super().closeEvent(event)
def initUI(self):
"""Creates UI window on launch."""
# Button for generating the master list.
btnGenMast = QPushButton('Run', self)
btnGenMast.move(450, 100)
btnGenMast.resize(100, 100)
btnGenMast.clicked.connect(self.genMastClicked)
# Create the text output widget.
self.process = QTextEdit(self, readOnly=True)
self.process.ensureCursorVisible()
self.process.setLineWrapColumnOrWidth(500)
self.process.setLineWrapMode(QTextEdit.FixedPixelWidth)
self.process.setFixedWidth(400)
self.process.setFixedHeight(150)
self.process.move(30, 100)
# Set window size and title, then show the window.
self.setGeometry(300, 300, 600, 300)
self.setWindowTitle('Generate Master')
self.show()
def genMastClicked(self):
"""Runs the main function."""
print('Running...')
time.sleep(5)
print('Done.')
if __name__ == '__main__':
# Run the application.
app = QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)
gui = GenMast()
sys.exit(app.exec_())
Сначала я попытался установить flush=True
в операторах печати.Однако меня встретила ошибка 'Stream' object has no attribute 'flush'
, поэтому я перешел к определению flush
в созданном мною классе Stream
следующим образом:
class Stream(QtCore.QObject):
"""Redirects console output to text widget."""
newText = QtCore.pyqtSignal(str)
def write(self, text):
self.newText.emit(str(text))
def flush(self):
sys.stdout.flush()
, что привело к ошибке RecursionError: maximum recursion depth exceeded
.На этом мое понимание заканчивается, так как я пробовал другие способы очистки буфера печати, но все они, похоже, имеют эту проблему.Любой совет, что я делаю не так?