Thanks to @musicamante, I realized I had to supply my own html template to export_html
. That was not immediately clear to me as its named a bit weird.
Not only was I injecting entire HTML pages into the TextEdit, but also the <pre>
tags that are used by default cause the spacing issues, so i used <div>
instead.
I also set the QTextEdit to use the monospace font that would normally be selected in the HTML stylesheet.
This is what ended up working:
class QTextEditLogger(QTextEdit, Handler):
"""A QTextEdit logger that uses RichHandler to format log messages."""
def __init__(self, parent=None, level=NOTSET):
QTextEdit.__init__(self, parent)
Handler.__init__(self,level=level)
self.console = Console(file=open(os.devnull, "wt"), record=True)
self.rich_handler = RichHandler(show_time=False, show_path=False, show_level=True, markup=True, console=self.console, level=self.level)
self.rich_handler.setLevel(self.level)
self.setWordWrapMode(QTextOption.WrapMode.WordWrap)
self.setAcceptRichText(True)
self.setReadOnly(True)
font = QFont(['Menlo','DejaVu Sans Mono','consolas','Courier New','monospace'], 10, self.font().weight())
font.setStyleHint(QFont.StyleHint.TypeWriter)
self.setFont(font)
def emit(self, record) -> None:
"""Override the emit method to handle log records."""
self.rich_handler.emit(record)
html_template = '<div style="background-color: {background}; color: {foreground};><code style="font-family:inherit">{code}</code><br/></div>'
html = self.console.export_html(clear=True, code_format=html_template, inline_styles=True)
self.insertHtml(html)
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())
c = self.textCursor()
c.movePosition(QTextCursor.End)
self.setTextCursor(c)