подскажите как вывод консоли Python передавать в виджет PyQt5

304 просмотра
0

Есть потребность вывод команд print() и системные сообщения об ошибках выводить не в консоль Python, а в виджет QTextEdit
понимаю, что нужно использовать sys.stdout и sys.stderr
но как фактически отправить не понимаю

как например оформить редирект команды print('Hello world') в вывод виджета?

Вот пример описания виджета. Он был автоматом сформирован в QT Designer и переведен в py через pyuic

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 271)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(0, 0, 801, 541))
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.textEdit = QtWidgets.QTextEdit(self.frame)
        self.textEdit.setGeometry(QtCore.QRect(0, 0, 801, 221))
        self.textEdit.setObjectName("textEdit")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.menuConvert = QtWidgets.QMenu(self.menubar)
        self.menuConvert.setObjectName("menuConvert")
        self.menuHelp = QtWidgets.QMenu(self.menubar)
        self.menuHelp.setObjectName("menuHelp")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actionOpen = QtWidgets.QAction(MainWindow)
        self.actionOpen.setObjectName("actionOpen")
        self.actionExit = QtWidgets.QAction(MainWindow)
        self.actionExit.setObjectName("actionExit")
        self.actionConvert_Nokia_contacts = QtWidgets.QAction(MainWindow)
        self.actionConvert_Nokia_contacts.setObjectName("actionConvert_Nokia_contacts")
        self.actionConvert_SPB_contacts = QtWidgets.QAction(MainWindow)
        self.actionConvert_SPB_contacts.setObjectName("actionConvert_SPB_contacts")
        self.actionInfo = QtWidgets.QAction(MainWindow)
        self.actionInfo.setObjectName("actionInfo")
        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addAction(self.actionExit)
        self.menuConvert.addAction(self.actionConvert_Nokia_contacts)
        self.menuConvert.addAction(self.actionConvert_SPB_contacts)
        self.menuHelp.addAction(self.actionInfo)
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuConvert.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())
 
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
 
 
        #Привязка действий к пунктам меню
        self.actionOpen.triggered.connect(self.OpenFile)
        self.actionConvert_Nokia_contacts.triggered.connect(self.Convert)
        self.actionConvert_SPB_contacts.triggered.connect(self.ConvertSPB)
        self.actionExit.triggered.connect(self.Exit)
 
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.textEdit.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:7.8pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Program is ready</p></body></html>"))
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.menuConvert.setTitle(_translate("MainWindow", "Convert"))
        self.menuHelp.setTitle(_translate("MainWindow", "Help"))
        self.actionOpen.setText(_translate("MainWindow", "Open"))
        self.actionExit.setText(_translate("MainWindow", "Exit"))
        self.actionConvert_Nokia_contacts.setText(_translate("MainWindow", "Convert Nokia contacts"))
        self.actionConvert_SPB_contacts.setText(_translate("MainWindow", "Convert SPB contacts"))
        self.actionInfo.setText(_translate("MainWindow", "Info"))
 
 
 
   def OpenFile(self):
        global op
        op = QFileDialog.getOpenFileName(self, 'Open file', '')[0]
        print(op)
        #l=input("")
        return(op)
 
    def Exit(self):
        import sys
        sys.exit()
 
    def Convert (OpenFile):
        global fpath
        print(op)
        f=str(op)
        import readfile
        readfile.workNokia(f)
        print('Process')
 
    def ConvertSPB (OpenFile):
        global fpath
        print(op)
        f=str(op)
        import spbn
        spbn.convert1(f)
        print('Process')
 
class Logger(object):
    def __init__(self, output):
        self.output = output
 
    def write(self, string):
        if not (string == "\n"):
            trstring = QtGui.QApplication.translate("MainWindow", string.strip(), None, QtGui.QApplication.UnicodeUTF8)
            self.output.append(trstring)
 
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())


Добавить комментарий

1 Ответы

Python Опубликовано 09.12.2018
0

Набросал небольшой пример, который перехватывает потоки stdout и stderr, и печатает их в QTextEdit.

OutputLogger — класс-обертка, который будет вызываться вместо объектов stdout и stderr. Кст, print по умолчанию в stdout и пишет.

OutputLoggerнаследуется от QObject чтобы была возможность использовать qt-шные сигналы.

После создания объекта OutputLogger нужно будет подключиться к его сигналу emit_write и обрабатывать его, например печатая текст в свой виджет (или отправляя по сети):

from PyQt5.QtWidgets import QMainWindow, QTextEdit, QMenuBar, QApplication
from PyQt5.QtCore import QObject
from PyQt5.QtCore import pyqtSignal as Signal
 
 
class OutputLogger(QObject):
    emit_write = Signal(str, int)
 
    class Severity:
        DEBUG = 0
        ERROR = 1
 
    def __init__(self, io_stream, severity):
        super().__init__()
 
        self.io_stream = io_stream
        self.severity = severity
 
    def write(self, text):
        self.io_stream.write(text)
        self.emit_write.emit(text, self.severity)
 
    def flush(self):
        self.io_stream.flush()
 
 
import sys
OUTPUT_LOGGER_STDOUT = OutputLogger(sys.stdout, OutputLogger.Severity.DEBUG)
OUTPUT_LOGGER_STDERR = OutputLogger(sys.stderr, OutputLogger.Severity.ERROR)
 
sys.stdout = OUTPUT_LOGGER_STDOUT
sys.stderr = OUTPUT_LOGGER_STDERR
 
 
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
 
        self.text_edit = QTextEdit()
 
        OUTPUT_LOGGER_STDOUT.emit_write.connect(self.append_log)
        OUTPUT_LOGGER_STDERR.emit_write.connect(self.append_log)
 
        menu_bar = QMenuBar()
        menu = menu_bar.addMenu('Say')
        menu.addAction('hello', lambda: print('Hello!'))
        menu.addAction('fail', lambda: print('Fail!', file=sys.stderr))
        self.setMenuBar(menu_bar)
 
        self.setCentralWidget(self.text_edit)
 
    def append_log(self, text, severity):
        text = repr(text)
 
        if severity == OutputLogger.Severity.ERROR:
            self.text_edit.append('<b>{}</b>'.format(text))
        else:
            self.text_edit.append(text)
 
 
if __name__ == '__main__':
    app = QApplication([])
 
    mw = MainWindow()
    mw.show()
 
    print('Go!')
 
    app.exec()


введите сюда описание изображения


Более сложный пример можно посмотреть тут.

Добавить комментарий
Напишите свой ответ на данный вопрос.
Scroll Up