在GUI记录器中添加颜色

时间:2019-02-13 15:27:50

标签: python logging pyqt formatting handler

在我的GUI中,我有一个小部件,可在其中复制主要代码中的日志消息

像这样:

import logging
from PyQt4 import Qt, QtCore,QtGui

class QPlainTextEditLogger(logging.Handler):
    """
    class that defines a handler to write logging message inside the GUI
    the geometry and position of the TextEdit is defined here, not by QT designer
    """
    err_fmt = "%(levelname)-8s %(message)s"
    dbg_fmt = "%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s"
    info_fmt = "%(levelname)-8s %(message)s"


    def __init__(self, parent):
        super().__init__()
        #first creates a text edit widget (parent is the main gui)
        self.widget = QtGui.QPlainTextEdit(parent)
        #adding this newly created widget to gridLayout_4
        parent.gridLayout_4.addWidget(self.widget,4, 0, 1, 2)
        #self.widget.setGeometry(11,583,337,213)

        self.widget.setReadOnly(True)


    def emit(self, record):

        msg = self.format(record)
        self.widget.appendPlainText(msg)

根据我在主代码中定义的格式,输出是黑白的,而终端中的输出是彩色的

class MyFormatter(logging.Formatter):
    """
    class to handle the logging formatting
    """
    # ----------------------------
    PURPLE = '\033[95m'
    CYAN = '\033[96m'
    DARKCYAN = '\033[36m'
    BLUE = '\033[94m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    RED = '\033[91m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'
    END = '\033[0m'


    err_fmt     = "[%(levelname)-8s] %(message)s"
    dbg_fmt     = "[%(levelname)-8s] [%(filename)s:%(lineno)d] %(message)s"
    dbgplus_fmt = "[%(levelname)-8s] (%(filename)s:%(lineno)d) %(message)s"
    info_fmt    = "[%(levelname)-8s] %(message)s"

    # FORMAT = "[$BOLD%(name)-20s$RESET][%(levelname)-18s]  %(message)s ($BOLD%(filename)s$RESET:%(lineno)d)"

    #format = "[$BOLD%(name)-20s$RESET][%(levelname)-18s]  %(message)s ($BOLD%(filename)s$RESET:%(lineno)d)"



    # def __init__(self):
    #     super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')

    def format(self, record):

        # Save the original format configured by the user
        # when the logger formatter was instantiated
        format_orig = self._style._fmt

        # Replace the original format with one customized by logging level
        if record.levelno == logging.DEBUG:

            self._style._fmt = formatter_message(MyFormatter.dbg_fmt,True)


      #      color = '\x1b[35;1m'

        elif record.levelno == logging.INFO:
            self._style._fmt = formatter_message(MyFormatter.info_fmt,True)
       #     color = '\x1b[32;1m'

        elif record.levelno == logging.ERROR:
            self._style._fmt = formatter_message(MyFormatter.err_fmt,True)
        #    color = '\x1b[31;1m'
        elif record.levelno == 5:
            self._style._fmt = formatter_message(MyFormatter.dbgplus_fmt,True)
         #   color = '\x1b[33;1m'

        levelname_color = COLOR_SEQ % (30 + COLORS[levelname]) + levelname + RESET_SEQ
        record.levelname = levelname_color


        # Call the original formatter class to do the grunt work
        result = logging.Formatter.format(self, record)

        # Restore the original format configured by the user
        self._style._fmt = format_orig

        return result

有没有一种方法可以在小部件中导入相同的格式?

1 个答案:

答案 0 :(得分:1)

可能的选择是使用HTML:

import logging
from PyQt4 import QtCore, QtGui

class CustomFormatter(logging.Formatter):
    FORMATS = {
        logging.ERROR:   ("[%(levelname)-8s] %(message)s", QtGui.QColor("red")),
        logging.DEBUG:   ("[%(levelname)-8s] [%(filename)s:%(lineno)d] %(message)s", "green"),
        logging.INFO:    ("[%(levelname)-8s] %(message)s", "#0000FF"),
        logging.WARNING: ('%(asctime)s - %(name)s - %(levelname)s - %(message)s', QtGui.QColor(100, 100, 0))
    }

    def format( self, record ):
        last_fmt = self._style._fmt
        opt = CustomFormatter.FORMATS.get(record.levelno)
        if opt:
            fmt, color = opt
            self._style._fmt = "<font color=\"{}\">{}</font>".format(QtGui.QColor(color).name(),fmt)
        res = logging.Formatter.format( self, record )
        self._style._fmt = last_fmt
        return res

class QPlainTextEditLogger(logging.Handler):
    def __init__(self, parent=None):
        super().__init__()
        self.widget = QtGui.QPlainTextEdit(parent)
        self.widget.setReadOnly(True)    

    def emit(self, record):
        msg = self.format(record)
        self.widget.appendHtml(msg) 
        # move scrollbar
        scrollbar = self.widget.verticalScrollBar()
        scrollbar.setValue(scrollbar.maximum())

class Dialog(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        logTextBox = QPlainTextEditLogger()
        logging.getLogger().addHandler(logTextBox)
        logTextBox.setFormatter(CustomFormatter())
        logging.getLogger().setLevel(logging.DEBUG)

        lay = QtGui.QVBoxLayout(self)
        lay.addWidget(logTextBox.widget)

        QtCore.QTimer(self, interval=500, 
            timeout=self.on_timeout).start()

    @QtCore.pyqtSlot()
    def on_timeout(self):
        import random
        msgs = ( 
            lambda: logging.debug('damn, a bug'),
            lambda: logging.info('something to remember'),
            lambda: logging.warning('that\'s not right'),
            lambda: logging.error('foobar'),
            lambda: logging.critical('critical :-(')
        )
        random.choice(msgs)()

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = Dialog()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

enter image description here