Skip to content

Instantly share code, notes, and snippets.

@davidlatwe
Last active August 23, 2019 06:38
Show Gist options
  • Save davidlatwe/6188eb45a11b94ad2788caa0c8626d13 to your computer and use it in GitHub Desktop.
Save davidlatwe/6188eb45a11b94ad2788caa0c8626d13 to your computer and use it in GitHub Desktop.
from avalon.vendor.Qt import QtWidgets, QtCore, QtGui
from avalon.vendor import qtawesome
from avalon import tools, style
import logging
import threading
import time
main_logger = logging.getLogger()
main_logger.setLevel(logging.DEBUG)
stream = logging.StreamHandler()
main_logger.addHandler(stream)
class WidgetLogHandler(logging.Handler):
"""Pipe logs into widget
Args:
widget: QWidget instance that has `echo` signal
"""
def __init__(self, widget):
super(WidgetLogHandler, self).__init__()
self.widget = widget
format = "%(message)s"
formatter = logging.Formatter(format)
self.setFormatter(formatter)
def emit(self, record):
dotting = record.msg.endswith(".....")
try:
log = self.format(record)
level = record.levelno
self.widget.echo.emit(level, log, dotting)
except (KeyboardInterrupt, SystemExit):
raise
except Exception:
self.handleError(record)
class LogLevelIcon(QtWidgets.QWidget):
"""Icon by log level"""
def __init__(self, parent=None):
super(LogLevelIcon, self).__init__(parent)
self.level = logging.NOTSET
self.icons = {
logging.NOTSET: qtawesome.icon("fa.bell", color="#404040"),
logging.DEBUG: qtawesome.icon("fa.bell", color="#5AD594"),
logging.INFO: qtawesome.icon("fa.bell", color="#439BF2"),
logging.WARNING: qtawesome.icon("fa.bell", color="#EED14E"),
logging.ERROR: qtawesome.icon("fa.bell", color="#F53434"),
logging.CRITICAL: qtawesome.icon("fa.bell", color="#F34FC1"),
}
self.setMinimumSize(18, 18)
self.setMaximumSize(18, 18)
def paintEvent(self, event):
painter = QtGui.QPainter()
painter.begin(self)
painter.drawPixmap(0, 0, self.icons[self.level].pixmap(18, 18))
painter.end()
class StatusLineWidget(QtWidgets.QWidget):
"""Logging message receiver and displayer
Args:
logger: `logging.Logger` instance
"""
echo = QtCore.Signal(int, str, int)
def __init__(self, logger, parent=None):
super(StatusLineWidget, self).__init__(parent)
icon = LogLevelIcon()
line = QtWidgets.QLineEdit()
line.setReadOnly(True)
line.setStyleSheet("""
QLineEdit {
border: 0px;
padding: 0 8px;
color: #AAAAAA;
background: #363636;
}
""")
body = QtWidgets.QHBoxLayout(self)
body.addWidget(icon)
body.addWidget(line)
self.icon = icon
self.line = line
handler = WidgetLogHandler(self)
logger.addHandler(handler)
self.echo.connect(self.on_echo)
def on_echo(self, level, log, dotting=False):
icon = self.icon
line = self.line
ALARM = logging.WARNING
if icon.level >= ALARM and level < ALARM:
return
def _echo(level, log):
icon.level = level
icon.update()
line.setText(log)
if dotting:
# Display dot anim
if log.endswith("....."):
log = log[:-4]
else:
log += "."
_echo(level, log)
def animator():
self.on_echo(level, log, dotting)
tools.lib.schedule(animator, 300, channel="statusline")
else:
_echo(level, log)
if level < ALARM:
# Back to default state
tools.lib.schedule(lambda: _echo(0, ""),
10000,
channel="statusline")
class Window(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
status = StatusLineWidget(main_logger, self)
body = QtWidgets.QVBoxLayout(self)
body.addWidget(status)
self.status = status
self.make_log()
self.resize(200, 30)
def make_log(self):
def run():
time.sleep(2)
for i in range(10):
msg = "%d\nhaha" % i
time.sleep(1)
if i % 5 == 0:
main_logger.debug(msg)
if i % 5 == 1:
main_logger.info(msg)
if i % 5 == 2:
main_logger.warning(msg)
if i % 5 == 3:
main_logger.error(msg)
if i % 5 == 4:
main_logger.critical(msg)
threading.Thread(target=run, daemon=True).start()
if __name__ == "__main__":
main_logger.info("START")
app = QtWidgets.QApplication([])
window = Window()
window.setStyleSheet(style.load_stylesheet())
window.show()
app.exec_()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment