PyQt5. Вывод консольных логов в QTextEdit с использованием кастомной цветовой схемы
В данной реализации логи без проблем валятся в консоль и виджит QTextEdit, но по понятным причинам всё выводится в одном цвете. Подскажите, как можно использовать туже цветовую (или какую-то другую) схему во вкладке History в виджите QTextEdit?
# -*- coding: utf-8 -*-
import logging, sys
from PyQt5.QtGui import QFont, QTextCursor
from PyQt5.QtWidgets import (
QApplication, QGridLayout, QTextEdit, QMainWindow, QTabWidget,
QWidget, QGroupBox, QHBoxLayout, QVBoxLayout, QPushButton
)
LOG_FORMAT = "[%(asctime)s]:[%(filename)s:%(lineno)d] - %(levelname)s - %(name)s - %(message)s"
class CustomLogFormatter(logging.Formatter):
magenta = "\x1b[95m"
cyan = "\x1b[96m"
yellow = "\x1b[93m"
red = "\x1b[31m"
bold_red = "\x1b[31;1m"
reset = "\x1b[0m"
FORMATS = {
logging.DEBUG : magenta + LOG_FORMAT + reset,
logging.INFO : cyan + LOG_FORMAT + reset,
logging.WARNING : yellow + LOG_FORMAT + reset,
logging.ERROR : red + LOG_FORMAT + reset,
logging.CRITICAL: bold_red + LOG_FORMAT + reset
}
def format(self, message):
log_fmt = self.FORMATS.get(message.levelno)
formatter = logging.Formatter(log_fmt)
return formatter.format(message)
class MainApp(QMainWindow):
"""
---=== Main Application Window Interface Class ===---
"""
def __init__(self):
super().__init__()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.resize(800, 500)
self.setWindowTitle("Application")
self.main_app_build()
def main_app_build(self):
tab1 = Tab1()
tab_history = TabHistory()
self.tabs = QTabWidget()
self.tabs.addTab(tab1, "Tab1")
self.tabs.addTab(tab_history, "History")
g_layout = QGridLayout(self.centralWidget)
g_layout.addWidget(self.tabs)
logger.info("Application Run")
class Tab1(QWidget):
"""
---=== Tab CUCM - Main Interface Class of CUCM Tab ===---
"""
def __init__(self, parent=None):
super().__init__(parent)
tasks_buttons = QPushButton("LOG RUN")
tasks_buttons.clicked.connect(self.log_gen)
self.h_layout = QHBoxLayout(self)
self.h_layout.addWidget(tasks_buttons)
def log_gen(self):
logger.debug("DEBUG BLA BLA BLA")
logger.info("INFO BLA BLA BLA")
logger.warning("WARNING BLA BLA BLA")
logger.error("ERROR BLA BLA BLA")
logger.critical("CRITICAL BLA BLA BLA")
class TabHistory(QWidget):
def __init__(self, parent=None):
super(TabHistory, self).__init__(parent)
self.history_text = QTextEdit()
self.history_text.setStyleSheet("""
QTextEdit {
background-color: #000;
color: #00ff00
}""")
h_layout = QHBoxLayout(self)
h_layout.addWidget(self.history_text)
history_box = QGroupBox()
history_box.setTitle("&History")
history_box.setFont(QFont("Helvetica", 10, QFont.Normal, italic=False))
history_box.setLayout(h_layout)
v_layout = QVBoxLayout(self)
v_layout.addWidget(history_box)
sys.stdout.write = self.request_std(sys.stdout.write)
sys.stderr.write = self.request_std(sys.stderr.write)
def request_std(self, func):
def inner(inputStr):
cursor = QTextCursor(self.history_text.document())
cursor.setPosition(0)
self.history_text.setTextCursor(cursor)
self.history_text.insertPlainText(inputStr)
return func(inputStr)
return inner
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(CustomLogFormatter())
stream_handler.setLevel(logging.DEBUG)
logger.addHandler(stream_handler)
logger = logging.getLogger("* Test App *")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MainApp()
ex.show()
sys.exit(app.exec_())
Ответы (1 шт):
Автор решения: Luarvick
→ Ссылка
Спасибо за подсказку @insolor. Проблему решил добавлением класса QTextEditLogger (https://stackoverflow.com/questions/28655198/best-way-to-display-logs-in-pyqt) и изменением класса TabHistory. Было бы интерерсно глянуть другие варианты решения задачи.
Измененный код.
class QTextEditLogger(logging.Handler):
def __init__(self, parent):
super().__init__()
self.widget = QTextEdit(parent)
self.widget.setReadOnly(True)
self.widget.setStyleSheet("""
QTextEdit {
background-color: #000;
}""")
def emit(self, record):
log_message = self.format(record)
if "DEBUG" in log_message:
text = f"""<span style='color:#ff00ff;'>{log_message}</span>"""
elif "INFO" in log_message:
text = f"""<span style='color:#00ffff;'>{log_message}</span>"""
elif "WARNING" in log_message:
text = f"""<span style='color:#ffff00;'>{log_message}</span>"""
elif "ERROR" in log_message or "CRITICAL" in log_message:
text = f"""<span style='color:#ff0000;'>{log_message}</span>"""
self.widget.append(text)
class TabHistory(QWidget):
def __init__(self, parent=None):
super(TabHistory, self).__init__(parent)
custom_handler = QTextEditLogger(self)
custom_handler.setFormatter(logging.Formatter(LOG_FORMAT))
custom_handler.setLevel(logging.DEBUG)
logging.getLogger().addHandler(custom_handler)
history_text = custom_handler.widget
h_layout = QHBoxLayout(self)
h_layout.addWidget(history_text)
history_box = QGroupBox()
history_box.setTitle("&History")
history_box.setFont(QFont("Helvetica", 10, QFont.Normal, italic=False))
history_box.setLayout(h_layout)
v_layout = QVBoxLayout(self)
v_layout.addWidget(history_box)

