Skip to content

ProgressBar

oldmangan edited this page Oct 6, 2026 · 1 revision

A progress bar: determinate or indeterminate, with a label, a value readout and four states. It comes in two forms that look identical: a live ProgressBar widget, and progress_html() for UIs built as HTML strings.

from wapyt import ProgressBar, ProgressBarConfig, progress_html

bar = ProgressBar(ProgressBarConfig(label="report.pdf", max=total, compact=True,
                                    label_width=110, value_width="7.5em"),
                  container=row_element)

def on_progress(seen, total):
    bar.set_value(seen, total, text=f"{seen * 100 // total}%  {format_size(seen)}")

bar.set_state("done")

The widget

Construct it with container= (an element or a layout cell) or root= (a selector), or mount it in a cell with Layout.add_progressbar(id, config).

ProgressBarConfig
value, max Progress as value of max (default 100), clamped to 0..max
label Text before the bar, such as a file name (set as text)
show_value Show the percentage when no value_text is given
value_text Replaces the "42%" readout, e.g. "42% 1.2 MB"
state "active" (blue), "done" (green), "error" (red), "paused" (amber)
indeterminate Total unknown: a sliding bar and no percentage
compact One line (label, bar, value) for rows, queues and tiles
label_width, value_width Fixed widths (px or any CSS size), so the bars of a stacked list line up
Method
set_value(value, max=None, *, text=None) Move the bar; text replaces the readout, "" restores the percentage
set_state(state) active / done / error / paused
set_indeterminate(True) Unknown total. Pass what you do know as text: set_value(0, text="1.9 MB received")
set_label(label), destroy()

set_value only changes the fill width and two text nodes, so it's fine to call it from a transfer's progress callback several times a second.

Static markup: progress_html()

tile = f"<div class='tile'><b>CPU</b>{progress_html(0.73, 1, label='CPU', show_value=False)}</div>"

progress_html(value, max=100, *, label=None, text=None, state="active", compact=True, show_value=True) returns the same markup as the widget, with every string HTML-escaped and no JavaScript, for dashboards and other UIs built from strings. Pass a fraction with max=1, or a count with its total.

Accessibility and motion

Both forms carry role="progressbar" with aria-valuemin, aria-valuemax, aria-valuenow and aria-valuetext, and the label as aria-label. An indeterminate bar omits aria-valuenow. With prefers-reduced-motion, the sliding bar becomes a static, dimmed bar and value changes don't animate.

Theming

The fill colour comes from --wapyt-progress-fill, which the states set. Override it to match an app, e.g. .my-tile .wapyt-progress { --wapyt-progress-fill: #a78bfa; }. The bars follow set_theme().

Clone this wiki locally