#python #многопоточность #pyqt5 #логирование
Как сделать так что-бы сообщения из модуля logging выходили в окне QPlainTextEdit.Желательно показать на моём примере как из потока вывести сообщение по завершению действия функции,так и без потока.По сути логирование программы. # -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'stacword.ui' # # Created by: PyQt5 UI code generator 5.11.3 # # WARNING! All changes made in this file will be lost! import logging import sys from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(316, 324) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(110, 240, 75, 23)) self.pushButton.setObjectName("pushButton") self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget) self.plainTextEdit.setGeometry(QtCore.QRect(10, 10, 291, 131)) self.plainTextEdit.setObjectName("plainTextEdit") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(130, 180, 47, 13)) self.label.setObjectName("label") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "PushButton")) self.label.setText(_translate("MainWindow", "TextLabel")) class ExampleApp(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) self.plainTextEdit.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) # Делает QPlainTextEdit только для вывода self.thread = WorkThread() self.pushButton.clicked.connect(self.func1) logging.basicConfig(level=logging.DEBUG) logging.info(u'This is an info message') def func1(self): # Создаем поток self.thread.start() class WorkThread(QtCore.QThread): ''' Потоковая задача ''' threadSignal = QtCore.pyqtSignal(int) def __init__(self): super().__init__() def run(self): # После окончания работы этой фукции в потоке,вывести сообщение от модуля logging в QPlainTextEdit for i in range(10): self.msleep(200) print(i) self.threadSignal.emit(i) def main(): app = QtWidgets.QApplication(sys.argv) # Новый экземпляр QApplication window = ExampleApp() # Создаём объект класса ExampleApp window.show() # Показываем окно app.exec_() if __name__ == '__main__': main()
Ответы
Ответ 1
Как вариант: import logging import sys from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(316, 324) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(110, 240, 75, 23)) self.pushButton.setObjectName("pushButton") self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget) self.plainTextEdit.setGeometry(QtCore.QRect(10, 10, 291, 131)) self.plainTextEdit.setObjectName("plainTextEdit") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(130, 180, 47, 13)) self.label.setObjectName("label") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "PushButton")) self.label.setText(_translate("MainWindow", "TextLabel")) # +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv class QTextEditLogger(logging.Handler): def __init__(self, parent): super().__init__() self.widget = parent.plainTextEdit self.widget.setReadOnly(True) def emit(self, record): msg = self.format(record) self.widget.appendPlainText(msg) # +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ class ExampleApp(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) # +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv logTextBox = QTextEditLogger(self) logTextBox.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')) logging.getLogger().addHandler(logTextBox) logging.getLogger().setLevel(logging.DEBUG) # +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # Делает QPlainTextEdit только для вывода self.plainTextEdit.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) self.thread = WorkThread() self.thread.threadSignal.connect(self.func2) # +++ self.pushButton.clicked.connect(self.func1) logging.debug("Это сообщение об отладке") logging.info(u'This is an info message') def func1(self): # Создаем поток self.thread.start() def func2(self, value): # +++ logging.info("Передано из потока -> {}".format(value)) # +++ class WorkThread(QtCore.QThread): ''' Потоковая задача ''' threadSignal = QtCore.pyqtSignal(int) def __init__(self): super().__init__() def run(self): for i in range(10): self.msleep(200) # print(i) self.threadSignal.emit(i) def main(): app = QtWidgets.QApplication(sys.argv) window = ExampleApp() window.show() app.exec_() if __name__ == '__main__': main() каким образом можно вывести сообщение по завершению действия в потоке? import logging import sys from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(400, 324) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(110, 240, 75, 23)) self.pushButton.setObjectName("pushButton") self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget) self.plainTextEdit.setGeometry(QtCore.QRect(10, 10, 370, 131)) self.plainTextEdit.setObjectName("plainTextEdit") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(130, 180, 47, 13)) self.label.setObjectName("label") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "PushButton")) self.label.setText(_translate("MainWindow", "TextLabel")) class QTextEditLogger(logging.Handler): def __init__(self, parent): super().__init__() self.widget = parent.plainTextEdit self.widget.setReadOnly(True) def emit(self, record): msg = self.format(record) self.widget.appendPlainText(msg) class ExampleApp(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) logTextBox = QTextEditLogger(self) logTextBox.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')) logging.getLogger().addHandler(logTextBox) logging.getLogger().setLevel(logging.DEBUG) layout = QtWidgets.QVBoxLayout(self.centralwidget) # +++ layout.addWidget(self.plainTextEdit) layout.addWidget(self.label) layout.addWidget(self.pushButton) self.plainTextEdit.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) self.thread = WorkThread() self.thread.threadSignal.connect(self.func2) self.thread.finishSignal.connect(self.func3) # +++ self.pushButton.clicked.connect(self.func1) logging.debug("Это сообщение об отладке") logging.info('This is an info message') def func1(self): # Создаем поток self.thread.start() def func2(self, value): logging.info("Передано из потока -> {}".format(value)) def func3(self): logging.info("Программа зевершена") class WorkThread(QtCore.QThread): ''' Потоковая задача ''' threadSignal = QtCore.pyqtSignal(int) finishSignal = QtCore.pyqtSignal() # +++ def __init__(self): super().__init__() def run(self): for i in range(10): self.msleep(200) self.threadSignal.emit(i) self.finishSignal.emit() # +++ def main(): app = QtWidgets.QApplication(sys.argv) window = ExampleApp() window.show() app.exec_() if __name__ == '__main__': main()
Комментариев нет:
Отправить комментарий