Source code for dlab.utils.log_panel
import datetime
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QTextEdit, QVBoxLayout, QWidget
[docs]
class LogPanel(QWidget):
"""A floating window for centralized timestamped log messages."""
def __init__(self, time_fmt: str = "%H:%M:%S", max_lines: int = 500):
super().__init__()
self._time_fmt = time_fmt
self._max_lines = max_lines
self._setup_ui()
def _setup_ui(self):
self.setWindowTitle("Log")
self.setWindowFlags(self.windowFlags() | Qt.WindowType.Window)
self.resize(500, 300)
layout = QVBoxLayout(self)
layout.setContentsMargins(4, 4, 4, 4)
self._text = QTextEdit()
self._text.setReadOnly(True)
layout.addWidget(self._text)
[docs]
def log(self, message: str, source: str | None = None):
"""Append a timestamped message, optionally with a source prefix."""
timestamp = datetime.datetime.now().strftime(self._time_fmt)
if source:
self._text.append(f"[{timestamp}] [{source}] {message}")
else:
self._text.append(f"[{timestamp}] {message}")
self._trim_if_needed()
[docs]
def logger(self, source: str):
"""Return a callable that logs with a fixed source prefix."""
return lambda message: self.log(message, source)
def _trim_if_needed(self):
"""Remove old lines if exceeding max_lines."""
doc = self._text.document()
if doc and doc.blockCount() > self._max_lines:
cursor = self._text.textCursor()
cursor.movePosition(cursor.Start)
cursor.movePosition(cursor.Down, cursor.KeepAnchor, 50)
cursor.removeSelectedText()
[docs]
def eventFilter(self, obj, event):
if obj == self._log and event.type() == event.Close:
self._log_button.setText("Show Log")
return super().eventFilter(obj, event)