Source code for qtdraw.widget.logging_util

"""
Logging utility.

This module provides utilities for logging.
"""

import sys
import os
import logging
from PySide6.QtWidgets import QWidget, QPlainTextEdit, QGridLayout, QFileDialog
from PySide6.QtGui import QFont

from qtdraw.widget.qt_event_util import ExceptionHook


# ==================================================
[docs] class LogHandler(logging.Handler): # ================================================== def __init__(self, level=logging.DEBUG, stream=None, text_widget=None): """ Log handler. Args: level (Level, optional): log level. stream (TextIO, optional): stream. text_widget (LogWidget, optional): text widget. Note: - if stream/text_widget is None, it is not used. """ super().__init__() # set handler. fmt = "%(asctime)s | %(levelname)8s | %(message)s" date_fmt = "%Y-%m-%d %H:%M:%S" self.setLevel(level) logging.basicConfig(level=level, format=fmt, datefmt=date_fmt, handlers=[self], encoding="utf-8") self.header = False # set plain text widget. if text_widget is not None: self.text_widget = text_widget # set stream. self.stream = stream # ==================================================
[docs] def emit(self, record): """ Emit message. Args: record (LogRecord): log record. """ if not self.header: header = " Date Time | Level | Message" if self.text_widget is not None: self.text_widget.append_text(header) if self.stream is not None: print(header, file=self.stream) self.header = True msg = self.format(record) if self.text_widget is not None: self.text_widget.append_text(msg) if self.stream is not None: print(msg, file=self.stream)
# ==================================================
[docs] def start_logging(level=logging.DEBUG, stream=None, text_widget=None, hook=True): """ Start logging. Args: level (Level, optional): logging level. stream (TextIO, optional): stream for logging. text_widget (LogWidget, optional): text widget. hook (bool, optional): exception hook ? Note: - stream is True, sys.stderr is used. """ if stream is True: stream = sys.stderr log_handler = LogHandler(level=level, stream=stream, text_widget=text_widget) logging.getLogger().addHandler(log_handler) if hook: ExceptionHook()
# ==================================================
[docs] class LogWidget(QWidget): # ================================================== def __init__(self, parent=None, title="log message", level=logging.DEBUG, stream=None, hook=True): """ Log widget. Args: parent (QObject, optional): parent. title (str, optional): window title. level (Level, optional): log level. stream (TextIO, optional): stream for logging. hook (bool, optional): exception hook ? Note: - if stream is True, sys.stderr is used. - if level is None, no logging. """ super().__init__(parent) self.log = QPlainTextEdit(self) font = QFont("Monaco", 11) font.setStyleHint(QFont.TypeWriter) self.log.setFont(font) self.log.setReadOnly(True) if level is not None: start_logging(level, stream, self, hook) self.setWindowTitle(title) self.resize(640, 800) layout = QGridLayout(self) layout.setContentsMargins(10, 10, 10, 10) layout.setSpacing(10) layout.addWidget(self.log, 0, 0, 1, 1) # ==================================================
[docs] def append_text(self, text): """ Append text. Args: text (str): text. """ self.log.appendPlainText(text)
# ==================================================
[docs] def set_text(self, text): """ Set text. Args: text (str): text. """ self.clear() self.append_text(text)
# ==================================================
[docs] def clear(self): """ Clear log message. """ self.log.clear()
# ==================================================
[docs] def save(self): """ Save log message. """ full = os.getcwd() filename, _ = QFileDialog.getSaveFileName(self, dir=full, filter="log (*.log)") if filename != "": with open(filename, "a") as f: print(self.log.plainText, file=f)