Implement a Progress Bar widget. (#2333)

* First prototype of PB.

* Repurpose UnderlineBar.

* Factor out 'Bar' widget.

* Revert "Factor out 'Bar' widget."

This reverts commit 0bb4871adf.

* Add Bar widget.

* Cap progress at 100%.

* Add skeleton for the ETA label.

[skip ci]

* Add ETA display.

* Improve docstrings.

* Directly compute percentage.

* Watch percentage changes directly.

[skip ci]

* Documentation.

* Make reactive percentage private.

Instead, we create a public read-only percentage property.

* Update griffe to fix documentation issue.

Related issues: #1572, https://github.com/mkdocstrings/griffe/issues/128.
Related PRs: https://github.com/mkdocstrings/griffe/pull/135.

* Add example and docs.

* Address review feedback.

[skip ci]

* More documentation.

* Add tests.

* Changelog.

* More tests.

* Fix/fake tests.

* Final tweaks.
This commit is contained in:
Rodrigo Girão Serrão
2023-04-26 15:25:39 +01:00
committed by GitHub
parent ee0d407067
commit 4148b1d450
20 changed files with 2242 additions and 262 deletions

View File

@@ -0,0 +1,46 @@
from textual.app import App, ComposeResult
from textual.containers import Center, Middle
from textual.timer import Timer
from textual.widgets import Footer, ProgressBar
class IndeterminateProgressBar(App[None]):
BINDINGS = [("s", "start", "Start")]
progress_timer: Timer
"""Timer to simulate progress happening."""
def compose(self) -> ComposeResult:
with Center():
with Middle():
yield ProgressBar()
yield Footer()
def on_mount(self) -> None:
"""Set up a timer to simulate progess happening."""
self.progress_timer = self.set_interval(1 / 10, self.make_progress, pause=True)
def make_progress(self) -> None:
"""Called automatically to advance the progress bar."""
self.query_one(ProgressBar).advance(1)
def action_start(self) -> None:
"""Start the progress tracking."""
self.query_one(ProgressBar).update(total=100)
self.progress_timer.resume()
def key_f(self) -> None:
# Freeze time for the indeterminate progress bar.
self.query_one(ProgressBar).query_one("#bar")._get_elapsed_time = lambda: 5
def key_t(self) -> None:
# Freeze time to show always the same ETA.
self.query_one(ProgressBar).query_one("#eta")._get_elapsed_time = lambda: 3.9
self.query_one(ProgressBar).update(total=100, progress=39)
def key_u(self) -> None:
self.query_one(ProgressBar).update(total=100, progress=100)
if __name__ == "__main__":
IndeterminateProgressBar().run()