Skip to content

Console

ui.Log collects entries (thread-safe, capped at limit, repeated lines folded) and can capture print and tracebacks. ui.console shows them like a browser’s dev tools console: a filter box, one toggle per level with its count, copy and clear. Levels are debug, info, event, stdout, stderr, warning and error (ui.LOG_LEVELS). With a ui.LogSelection the lines can be selected (click, Shift+click, Ctrl+click) and a selected line shows its detail (a traceback); on_context opens your menu on right click, and sources adds a dropdown to show the lines of one source.

ui.console · Category: Code and tools · Full reference →

ConsoleConsole
  • For a debug panel in your app, or to show what a background job is doing.
import pyzed as pz
from pyzed import ui
class Debug(pz.App):
def __init__(self):
self.log = ui.Log(on_write=lambda: pz.post("log")) # redraw when a line arrives
self.log.capture() # also collect print() and stderr
self.query, self.hidden = "", set()
def view(self):
return ui.console(self.log.entries, query=self.query,
on_query=lambda q: setattr(self, "query", q),
hidden=self.hidden, on_toggle_level=lambda lvl: self.hidden.symmetric_difference_update({lvl}),
on_clear=self.log.clear, on_copy=lambda: pz.Command.copy(self.log.text()))
Console: All levelsConsole: All levels
All levels
Code
log = ui.Log()
for level in ui.LOG_LEVELS:
log.write(level, f"{level} message")
pz.container(ui.console(log.entries, on_clear=on_clear), width=520, height=220)
Console: hidden={"info", "event"}Console: hidden={"info", "event"}
hidden={"info", "event"}
Code
log = ui.Log()
for level in ui.LOG_LEVELS:
log.write(level, f"{level} message")
pz.container(ui.console(log.entries, hidden={"info", "event"}, on_toggle_level=on_toggle),
width=520, height=200)
Console: query="error"Console: query="error"
query="error"
Code
log = ui.Log()
log.write("info", "started")
log.write("error", "ValueError: bad input")
pz.container(ui.console(log.entries, query="error", on_query=on_query), width=520, height=140)

Console has 8 events of its own, listed below. Like every widget it also has the 18 common events (click, double_click, right_click, mouse_enter, drag, key_down, resize…), attached with .on(...): see Events and Events of every component.

Event Of Handler gets When
on_query ui.console (text) Receives each edit of the filter.
on_toggle_level ui.console (level) Called with the level of the clicked toggle.
on_clear ui.console () Adds a Clear button.
on_copy ui.console () Adds a Copy button.
on_context ui.console (line) Called with the line right-clicked (None under the lines): open a menu there (copy, go to source, clear…).
on_open ui.console (line) Called with the line double-clicked.
on_source ui.console (source) Receives the source picked in the dropdown (None for all).
on_write ui.Log () Called after every write (from any thread).

Handler gets is what Pyzed passes to your callable: () means nothing. Any handler can also be a message (a value that is not callable), which goes to update().

The same events written three ways. Imperative: methods of the app change self. Declarative: the handlers produce messages and one update() decides. Functional: a pure function draws an immutable state and asks for changes with set_state(...). See Imperative, declarative and functional.

class Debug(pz.App):
def __init__(self):
self.log = ui.Log()
self.log.write("info", "Started")
self.log.write("error", "ValueError: bad input")
self.log.on_write = lambda: pz.post("log") # a line arrived (from any thread)
self.query, self.hidden = "", set()
def update(self, message):
pass # "log" just redraws
def view(self):
return ui.console(self.log.entries, query=self.query, hidden=self.hidden,
on_query=lambda q: setattr(self, "query", q), # the filter
on_toggle_level=lambda lvl: self.hidden.symmetric_difference_update({lvl}),
on_clear=self.log.clear, # adds Clear
on_copy=lambda: pz.Command.copy(self.log.text()), # adds Copy
on_open=lambda entry: print("open", entry.text)) # double click
console(
entries,
*,
query='',
on_query=None,
hidden=(),
on_toggle_level=None,
on_clear=None,
on_copy=None,
actions=(),
selection=None,
on_context=None,
on_open=None,
sources=(),
source=None,
on_source=None,
show_source=False,
placeholder=None,
empty=None,
font_size=12.5,
id=None,
theme=None,
)

A log view like a browser’s dev tools console: a filter box, one toggle per level with its count, copy and clear, and the entries in a monospace list that keeps scrolling to the newest one.

Property Default Description
entries required ui.LogEntry items (log.entries).
query "" Filter text.
hidden () Levels not shown.
actions () Extra widgets at the end of the toolbar.
selection None A ui.LogSelection: the lines can be selected with the mouse, and a selected line with detail shows it below.
sources () (value, label) pairs: adds a dropdown that shows the lines of one source.
source None The source shown (None for all).
show_source False Tags each line with its source.
placeholder None Text of the empty filter box.
empty None What shows while there are no lines.
font_size 12.5 Size of the entries.
id None Scrollable id.
theme None Theme to use instead of the current one (pyzed.theme.current()).

Events: on_query, on_toggle_level, on_clear, on_copy, on_context, on_open, on_source (events).

Full reference →

class Log

The entries of a ui.console: thread-safe, capped at limit, with repeated lines folded into one. write(level, text) adds a line; capture() (or with log:) copies print output and tracebacks into it; pipe(stream) reads a subprocess’s output in a background thread; text() returns everything for copying (text(ids) only those lines). write also takes the line’s source, detail (a traceback) and origin ((path, line)) and returns the entry; find(id) looks one up.

Property Default Description
limit 5000 Most entries kept.

Events: on_write (events).

Full reference →

@dataclass
class LogEntry(level, text, time=time.time(), count=1, source='', detail='', origin=None, id=0)

One line of a ui.Log: level, text, time, count (identical lines in a row), source, detail, origin, its number id, clock (HH:MM:SS) and line() (the entry as plain text).

Property Default Description
level required Level name.
text required The line.
time time() When it was written (time.time()).
count 1 Identical lines in a row.
source "" What it comes from ("project", "agent"…); ui.console can show and filter it.
detail "" More text shown under the line while it is selected (a traceback).
origin None (path, line) of the code it is about.
id 0 Its number in the log (what a ui.LogSelection keeps).

Full reference →

class LogSelection

The selected lines of a ui.console, like in a file list: a click selects one line, Shift+click a range from the last one clicked and Ctrl+click (Cmd on macOS) adds or removes one. Keep one in your app and pass it to ui.console(selection=...); select(ids) selects exactly those (Ctrl+A), clear() none, keep(entries) forgets lines that are gone, and ids are the selected entries’ ids for log.text(ids).

Full reference →

The levels ui.console colors, in the order of its filter buttons: debug, info, event, stdout, stderr, warning, error.

Full reference →