1#!/usr/bin/env python
2
3"""Example: messages of each severity in the footer of a window, each shown for five seconds.
4
5i, w and e post an info, a warning and an error message, s posts one that stays until it is dismissed,
6d dismisses the newest message, c clears them all, and q exits. The keys work in either case.
7"""
8
9from __future__ import annotations
10
11import itertools
12
13import urwid
14
15
16def main() -> None:
17 """Build the window with the notifications footer and the key handling, and run the main loop."""
18 notifications = urwid.Notifications(
19 max_count=5,
20 severity_attr={
21 urwid.Severity.INFO: "info",
22 urwid.Severity.WARNING: "warning",
23 urwid.Severity.ERROR: "error",
24 },
25 default="i: info w: warning e: error s: sticky d: dismiss c: clear q: quit",
26 default_attr="help",
27 )
28 numbers = itertools.count(1)
29 severities = {"i": urwid.Severity.INFO, "w": urwid.Severity.WARNING, "e": urwid.Severity.ERROR}
30
31 def unhandled(key: str | tuple[str, int, int, int]) -> None:
32 if not isinstance(key, str):
33 return
34 # Shift or Caps Lock sends the upper-case key
35 key = key.lower()
36 if key == "q":
37 raise urwid.ExitMainLoop
38 if key in severities:
39 severity = severities[key]
40 notifications.notify(f"{severity.name.lower()} message {next(numbers)}", severity=severity)
41 elif key == "s":
42 notifications.notify(f"sticky message {next(numbers)}, d dismisses it", timeout=None)
43 elif key == "d" and notifications.notifications:
44 notifications.dismiss(notifications.notifications[-1])
45 elif key == "c":
46 notifications.clear()
47
48 body = urwid.Filler(urwid.Text("Messages appear in the footer, oldest at the top.", align="center"))
49 frame: urwid.Frame[urwid.Filler[urwid.Text], None, urwid.Notifications] = urwid.Frame(body, footer=notifications)
50 palette: list[tuple[str, str, str]] = [
51 ("help", "black", "light gray"),
52 ("info", "white", "dark blue"),
53 ("warning", "black", "brown"),
54 ("error", "white", "dark red"),
55 ]
56 urwid.MainLoop(frame, palette, unhandled_input=unhandled).run()
57
58
59if __name__ == "__main__":
60 main()