![](/img/trans.png)
[英]Execute script in another thread and write output in real-time on gui (pyqt5)
[英]Redirect console output to pyqt5 gui in real time
我想使用 PyQt5 在 gui 中实时重定向 python 程序的控制台 output
我的意思是在每个 output python 程序中,gui会立即显示这个 output
我使用的代码仅在完成整个程序后才显示日志,并且没有解决实时问题
你能帮助我吗
在我的代码下面:
from PyQt5 import QtGui,QtCore
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import QtGui
from PyQt5.QtGui import QPixmap
class gui(QMainWindow):
def __init__(self):
super(gui, self).__init__()
self.initUI()
def dataReady(self):
cursor = self.output.textCursor()
cursor.movePosition(cursor.End)
cursor.insertText(str(self.process.readAll()))
self.output.ensureCursorVisible()
def callProgram(self):
# run the process
# `start` takes the exec and a list of arguments
self.process.start('python',['Robot.py'])
def initUI(self):
# Layout are better for placing widgets
layout = QHBoxLayout()
self.runButton = QPushButton('Run')
self.runButton.clicked.connect(self.callProgram)
self.output = QTextEdit()
self.setGeometry(100, 60, 1000, 800)
layout.addWidget(self.output)
layout.addWidget(self.runButton)
centralWidget = QWidget()
centralWidget.setLayout(layout)
self.setCentralWidget(centralWidget)
# QProcess object for external app
self.process = QtCore.QProcess(self)
# QProcess emits `readyRead` when there is data to be read
self.process.readyRead.connect(self.dataReady)
# Just to prevent accidentally running multiple times
# Disable the button when process starts, and enable it when it finishes
self.process.started.connect(lambda: self.runButton.setEnabled(False))
self.process.finished.connect(lambda: self.runButton.setEnabled(True))
#Function Main Start
def main():
app =QApplication(sys.argv)
ui=gui()
ui.show()
sys.exit(app.exec_())
#Function Main END
if __name__ == '__main__':
main() ```
当您将 python output 重定向到文件或 pipe 时,出于性能原因,它会被缓冲。 您需要使用-u
cli 参数运行脚本或刷新每个打印 output ,如下所示: print(something, flush=True)
。 有关详细信息,请参阅此问题。
self.process.start('python',['-u','Robot.py'])
这里的完整解决方案,感谢@mugiseybrows 和@eyllanesc
它解决了两个问题:第一个是在 gui 中重定向 python 程序的 output,第二个是在独立行中显示每个 output
import sys
from PyQt5 import QtGui,QtCore
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import QtGui
from PyQt5.QtGui import QPixmap
class gui(QMainWindow):
def __init__(self):
super(gui, self).__init__()
self.initUI()
def dataReady(self):
cursor = self.output.textCursor()
cursor.movePosition(cursor.End)
#cursor.insertText(str(self.process.readAll()))
cursor.insertText(self.process.readAll().data().decode())
self.output.ensureCursorVisible()
def callProgram(self):
# run the process
# `start` takes the exec and a list of arguments
self.process.start('python',['-u','Robot.py'])
def initUI(self):
# Layout are better for placing widgets
layout = QHBoxLayout()
self.runButton = QPushButton('Run')
self.runButton.clicked.connect(self.callProgram)
self.output = QTextEdit()
self.setGeometry(100, 60, 1000, 800)
layout.addWidget(self.output)
layout.addWidget(self.runButton)
centralWidget = QWidget()
centralWidget.setLayout(layout)
self.setCentralWidget(centralWidget)
# QProcess object for external app
self.process = QtCore.QProcess(self)
# QProcess emits `readyRead` when there is data to be read
self.process.readyRead.connect(self.dataReady)
# Just to prevent accidentally running multiple times
# Disable the button when process starts, and enable it when it finishes
self.process.started.connect(lambda: self.runButton.setEnabled(False))
self.process.finished.connect(lambda: self.runButton.setEnabled(True))
#Function Main Start
def main():
app =QApplication(sys.argv)
ui=gui()
ui.show()
sys.exit(app.exec_())
#Function Main END
if __name__ == '__main__':
main()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.