List Walker Classes

ListWalker

class urwid.ListWalker

Base class for objects that supply widgets to a ListBox on demand, by position.

get_focus() → tuple[_V_co, _K] | tuple[None, None]

Return the (widget, position) currently in focus.

This default implementation relies on a focus attribute and a __getitem__() method defined in a subclass.

Override and don’t call this method if these are not defined.

Returns:

(widget, position) or (None, None)

get_next(position: _K) → tuple[_V_co, _K] | tuple[None, None]

Return the (widget, position) after position.

This default implementation relies on a next_position() method and a __getitem__() method defined in a subclass.

Override and don’t call this method if these are not defined.

Parameters:

position – position to start from

Returns:

(widget, position) or (None, None)

get_prev(position: _K) → tuple[_V_co, _K] | tuple[None, None]

Return the (widget, position) before position.

This default implementation relies on a prev_position() method and a __getitem__() method defined in a subclass.

Override and don’t call this method if these are not defined.

Parameters:

position – position to start from

Returns:

(widget, position) or (None, None)

List-like List Walkers

class urwid.SimpleFocusListWalker(contents: Iterable[_T], wrap_around: bool = False, *, follow_end: bool = False)

ListWalker like SimpleListWalker that also keeps focus tracking items across edits.

Initialize a list walker, which can be treated as a list since it inherits MonitoredList.

Changes made to this object (when it is treated as a list) are detected automatically and will cause ListBox objects using this list walker to be updated.

Also, items added or removed before the widget in focus with normal list methods will cause the focus to be updated intelligently.

Parameters:
  • contents – list to copy into this object

  • wrap_around – if true, jumps to beginning/end of list on move

  • follow_end – if true, items added after a focused last item take the focus, so a ListBox showing a growing log keeps showing its newest line until the user moves the focus up; see MonitoredFocusList.follow_end

Raises:

ListWalkerError – contents is not iterable.

next_position(position: SupportsIndex) → int

Return position after position.

Parameters:

position – position to start from

Raises:

IndexError – if there is no next position and wrap_around is false

positions(*, reverse: bool = False) → Iterable[int]
positions(reverse: bool, /) → Iterable[int]

Return an iterable of positions. Optional method.

Parameters:
  • args – reverse passed positionally, the deprecated form

  • reverse – if true, return positions in reverse order

Raises:

TypeError – more than one positional argument is given, or reverse is given both ways.

Deprecated since version 5.0.0: Passing reverse positionally is deprecated. Pass it by keyword.

prev_position(position: SupportsIndex) → int

Return position before position.

Parameters:

position – position to start from

Raises:

IndexError – if there is no previous position and wrap_around is false

set_focus(position: int) → None

Set focus position.

Parameters:

position – position to focus

set_modified_callback(callback: Any) → NoReturn

Raise NotImplementedError: this function inherited from MonitoredList is not implemented here.

Use connect_signal(list_walker, "modified", ...) instead.

Raises:

NotImplementedError – always

class urwid.SimpleListWalker(contents: Iterable[_T], wrap_around: bool = False)

ListWalker that presents a plain list of widgets, addressed by integer position.

Initialize a list walker, which can be treated as a list since it inherits MonitoredList.

Changes made to this object (when it is treated as a list) are detected automatically and will cause ListBox objects using this list walker to be updated.

Parameters:
  • contents – list to copy into this object

  • wrap_around – if true, jumps to beginning/end of list on move

Raises:

ListWalkerError – contents is not iterable.

property contents: Self

Return self.

Provides compatibility with old SimpleListWalker class.

next_position(position: int) → int

Return position after position.

Parameters:

position – position to start from

Raises:

IndexError – if there is no next position and wrap_around is false

positions(*, reverse: bool = False) → Iterable[int]
positions(reverse: bool, /) → Iterable[int]

Return an iterable of positions. Optional method.

Parameters:
  • args – reverse passed positionally, the deprecated form

  • reverse – if true, return positions in reverse order

Raises:

TypeError – more than one positional argument is given, or reverse is given both ways.

Deprecated since version 5.0.0: Passing reverse positionally is deprecated. Pass it by keyword.

prev_position(position: int) → int

Return position before position.

Parameters:

position – position to start from

Raises:

IndexError – if there is no previous position and wrap_around is false

set_focus(position: int) → None

Set focus position.

Parameters:

position – position to focus

Raises:

IndexError – if there is no widget at position

set_modified_callback(callback: Callable[[], Any]) → NoReturn

Raise NotImplementedError: this function inherited from MonitoredList is not implemented here.

Use connect_signal(list_walker, "modified", ...) instead.

Raises:

NotImplementedError – always

Deque-like List Walkers

class urwid.SimpleFocusDequeWalker(contents: Iterable[_T], wrap_around: bool = False, maxlen: int | None = None, *, follow_end: bool = False)

A ListWalker backed by a MonitoredFocusDeque.

Mirrors SimpleFocusListWalker method-for-method, adapted to deque’s narrower API. See the performance caveat documented on SimpleDequeWalker – it applies equally here.

Build the walker, wrapping contents in a focus-tracking deque.

This class inherits MonitoredFocusDeque, which means it can be treated as a deque.

Changes made to this object (when it is treated as a deque) are detected automatically and will cause ListBox objects using this list walker to be updated.

Also, items added or removed before the widget in focus with normal deque methods – including eviction caused by maxlen – will cause the focus to be updated intelligently.

Parameters:
  • contents – iterable to copy into this object

  • wrap_around – if true, jumps to beginning/end of deque on move

  • maxlen – if set, bounds the deque’s length; the oldest items are silently evicted from the opposite end once full, and focus is adjusted to keep tracking a sensible item (see MonitoredFocusDeque)

  • follow_end – if true, items added after a focused last item take the focus, so a ListBox showing a growing log keeps showing its newest line until the user moves the focus up; see MonitoredFocusDeque.follow_end

Raises:

ListWalkerError – contents is not iterable.

copy() → Self

Return a shallow copy with the same capacity, wrapping and follow_end settings.

next_position(position: SupportsIndex) → int

Return position after position.

Parameters:

position – position to start from

Raises:

IndexError – if there is no next position and wrap_around is false

positions(*, reverse: bool = False) → Iterable[int]
positions(reverse: bool, /) → Iterable[int]

Return an iterable of positions. Optional method.

Parameters:
  • args – reverse passed positionally, the deprecated form

  • reverse – if true, return positions in reverse order

Raises:

TypeError – more than one positional argument is given, or reverse is given both ways.

Deprecated since version 5.0.0: Passing reverse positionally is deprecated. Pass it by keyword.

prev_position(position: SupportsIndex) → int

Return position before position.

Parameters:

position – position to start from

Raises:

IndexError – if there is no previous position and wrap_around is false

set_focus(position: int) → None

Set focus position.

Parameters:

position – position to focus

set_modified_callback(callback: Any) → NoReturn

Raise NotImplementedError: this function inherited from MonitoredFocusDeque is not implemented here.

Use connect_signal(list_walker, "modified", ...) instead.

Raises:

NotImplementedError – always

class urwid.SimpleDequeWalker(contents: Iterable[_T], wrap_around: bool = False, maxlen: int | None = None)

A ListWalker backed by a MonitoredDeque.

Mirrors SimpleListWalker method-for-method, adapted to deque’s narrower API (in particular, maxlen-bounded eviction).

Note

ListWalker.get_focus()/ListWalker.get_next()/ListWalker.get_prev() (inherited, unmodified) index via self[position], and deque.__getitem__ is O(n) (linked-block structure) rather than a list’s O(1) – worth bearing in mind for a very large unbounded deque, though the bounded/maxlen scrollback use case this class targets is small enough that it does not matter in practice. No caching layer is provided.

Initialize a deque walker, which can be treated as a deque since it inherits MonitoredDeque.

Changes made to this object (when it is treated as a deque) are detected automatically and will cause ListBox objects using this list walker to be updated.

Parameters:
  • contents – iterable to copy into this object

  • wrap_around – if true, jumps to beginning/end of deque on move

  • maxlen – if set, bounds the deque’s length; the oldest items are silently evicted from the opposite end once full

Raises:

ListWalkerError – contents is not iterable.

property contents: SimpleDequeWalker[_T]

Return self.

Provides compatibility with old SimpleListWalker class.

next_position(position: int) → int

Return position after position.

Parameters:

position – position to start from

Raises:

IndexError – if there is no next position and wrap_around is false

positions(*, reverse: bool = False) → Iterable[int]
positions(reverse: bool, /) → Iterable[int]

Return an iterable of positions. Optional method.

Parameters:
  • args – reverse passed positionally, the deprecated form

  • reverse – if true, return positions in reverse order

Raises:

TypeError – more than one positional argument is given, or reverse is given both ways.

Deprecated since version 5.0.0: Passing reverse positionally is deprecated. Pass it by keyword.

prev_position(position: int) → int

Return position before position.

Parameters:

position – position to start from

Raises:

IndexError – if there is no previous position and wrap_around is false

set_focus(position: int) → None

Set focus position.

Parameters:

position – position to focus

Raises:

IndexError – if there is no widget at position

set_modified_callback(callback: Callable[[], Any]) → NoReturn

Raise NotImplementedError: this function inherited from MonitoredDeque is not implemented here.

Use connect_signal(list_walker, "modified", ...) instead.

Raises:

NotImplementedError – always

Filtering List Walkers

class urwid.FilteredListWalker(source: ListWalker[int, _T] | Iterable[_T], *, predicate: Callable[[_T], bool] | None = None, wrap_around: bool = False)

A read-only view of a source list walker that shows only the items passing a predicate.

The positions of the view are the indices of the source, so a position taken from the view addresses the same item in source, and no mapping between two index spaces is needed. Items are added, removed and moved through source; the view has no methods that change the list. Every "modified" signal of the source re-applies the predicate, and the view emits its own "modified" once per such rebuild. That includes the signal the source’s own set_focus() emits; the view never changes the focus of the source.

The focus of the view stays on the same widget while that widget passes the predicate. When it does not:

  • after a change to the source, or refilter(), the focus moves to the next visible item at or after the old focus position, else to the last visible item;

  • after a change of the predicate, the focus moves to the first visible item.

An empty view has no focus. When the widget focused last becomes visible again, it takes the focus back.

A predicate that raises leaves the view as it was, except after a change to the source: the old positions may no longer exist there, so the view empties itself, emits "modified", and the exception reaches the code that changed the source. The next change to the source or the predicate fills the view again.

A rebuild walks the source once, so it is linear in the length of a list or a deque source. Reading one item or the focus indexes the source, which is linear for a deque, as SimpleDequeWalker notes.

>>> import urwid
>>> words = ("apple", "pear", "plum", "peach", "fig", "lime")
>>> view = urwid.FilteredListWalker([urwid.Text(word) for word in words])
>>> view.set_focus(2)
>>> list(view.positions())
[0, 1, 2, 3, 4, 5]
>>> view.set_predicate(lambda widget: widget.text.startswith("pe"))
>>> list(view.positions())
[1, 3]
>>> widget, position = view.get_focus()
>>> widget.text, position
('pear', 1)

Create a view of source that shows the items for which predicate returns true.

Parameters:
  • source – a list walker that is also a sequence, such as SimpleFocusListWalker, SimpleFocusDequeWalker or their non-focus variants. Any other iterable of widgets is copied into a new SimpleFocusListWalker.

  • predicate – called with each widget of the source; None shows every widget.

  • wrap_around – if true, moving past one end of the visible items continues at the other end.

Raises:
  • TypeError – source is a list walker that is not a sequence, such as a TreeWalker.

  • ListWalkerError – source is not iterable.

  • Exception – whatever predicate raises for a widget of source.

get_focus() → tuple[_T, int] | tuple[None, None]

Return the (widget, position) in focus, or (None, None) when no widget is visible.

next_position(position: int) → int

Return the visible position after position.

Raises:

IndexError – there is none and wrap_around is false.

positions(*, reverse: bool = False) → Iterator[int]

Return the visible positions in order.

Parameters:

reverse – return them from the last to the first.

property predicate: Callable[[_T], bool] | None

The function that decides which widgets are visible; None shows every widget.

prev_position(position: int) → int

Return the visible position before position.

Raises:

IndexError – there is none and wrap_around is false.

refilter() → None

Apply the predicate again, after widgets of the source changed in place.

Raises:

Exception – whatever the predicate raises; the view then keeps its previous items.

set_focus(position: int) → None

Move the focus to the visible source index position.

Raises:

IndexError – position is hidden by the predicate or out of range.

set_predicate(predicate: Callable[[_T], bool] | None) → None

Replace the predicate and show the widgets that pass it.

Parameters:

predicate – called with each widget of the source; None shows every widget.

Raises:

Exception – whatever predicate raises; the view then keeps its previous predicate and items.

property source: Sequence[_T]

The list walker whose items the view shows, and the one to add, remove or move items through.

TreeWalker and Nodes

class urwid.TreeWalker(start_from: TreeNode[Any])

ListWalker-compatible class for displaying TreeWidgets.

positions are TreeNodes.

start_from: TreeNode with the initial focus.

get_focus() → tuple[TreeWidget[TreeNode[Any]], TreeNode[Any]]

Return the widget and node currently in focus.

get_next(start_from: TreeNode[Any]) → tuple[TreeWidget[TreeNode[Any]], TreeNode[Any]] | tuple[None, None]

Return the widget and node that follow start_from depth first, or (None, None).

get_prev(start_from: TreeNode[Any]) → tuple[TreeWidget[TreeNode[Any]], TreeNode[Any]] | tuple[None, None]

Return the widget and node that precede start_from depth first, or (None, None).

positions(*, reverse: bool = False) → Iterator[TreeNode[Any]]

Yield the visible nodes of the focused node’s tree in display order.

The children of a collapsed node are not visible, so they are not yielded.

Parameters:

reverse – yield from the last visible node up to the root instead.

set_focus(focus: TreeNode[Any]) → None

Set the node in focus and notify listeners that the walker was modified.

class urwid.TreeNode(value: _T, parent: ParentNode[Any] | None = None, key: Hashable = None, depth: int | None = None)

Store tree contents and cache TreeWidget objects.

A TreeNode consists of the following elements: * key: accessor token for parent nodes * value: subclass-specific data * parent: a TreeNode which contains a pointer back to this object * widget: The widget used to render the object

Store value under key, with parent and depth as given, or computed from parent when omitted.

change_key(key: Hashable) → None

Rename this node to key, updating the parent’s reference to it as well.

Raises:

TreeWidgetError – this node is the root. The parent is not loaded yet and load_parent() is not overridden. key is already a key among the parent’s children, this node’s own key included.

get_depth() → int

Return this node’s depth in the tree, computing and caching it if necessary.

The ancestors are walked in a loop rather than recursively, so the depth of the tree is not limited by the interpreter’s recursion limit. Every ancestor whose depth was unknown caches its own depth as well. The walk stops at an ancestor whose class overrides this method, and uses the depth that ancestor returns.

Raises:

TreeWidgetError – the parent links form a cycle.

get_index() → int | None

Return this node’s position among its parent’s children, or None for the root.

get_key() → Hashable

Return this node’s key.

get_parent() → ParentNode[Any] | None

Return this node’s parent, loading it with load_parent() if necessary, or None for the root.

get_root() → TreeNode[Any]

Return the root node of the tree this node belongs to.

get_value() → _T

Return this node’s value.

get_widget(reload: bool = False) → TreeWidget[Self]

Return the widget for this node.

is_root() → bool

Return whether this node is the root of the tree.

load_parent() → ParentNode[Any]

Provide TreeNode with a parent for the current node.

This function is only required if the tree was instantiated from a child node (virtual function)

Raises:

TreeWidgetError – the subclass does not override this method.

load_widget() → TreeWidget[Self]

Create the widget for this node.

next_sibling() → TreeNode[Any] | None

Return the next sibling of this node, or None if there is none.

prev_sibling() → TreeNode[Any] | None

Return the previous sibling of this node, or None if there is none.

set_key(key: Hashable) → None

Set this node’s key without updating the parent’s reference to it.

class urwid.ParentNode(value: Any, parent: ParentNode[Any] | None = None, key: Hashable = None, depth: int | None = None)

Maintain sort order for TreeNodes.

Store value under key, with no child keys loaded yet.

change_child_key(oldkey: Hashable, newkey: Hashable) → None

Rename a child, moving it from oldkey to newkey.

Raises:

TreeWidgetError – newkey is already used by another child.

get_child_index(key: Hashable) → int

Return the position of the child key among the child keys.

Raises:

TreeWidgetError – key is not a child of this node.

get_child_keys(reload: bool = False) → Sequence[Hashable]

Return a possibly ordered list of child keys.

A reload also drops the cached child nodes whose keys are no longer in the list.

get_child_node(key: Hashable, reload: bool = False) → TreeNode[Any]

Return the child node for a given key. Create if necessary.

get_child_widget(key: Hashable) → TreeWidget[TreeNode[Any]]

Return the widget for a given key. Create if necessary.

get_first_child() → TreeNode[Any]

Return the first TreeNode in the directory.

get_last_child() → TreeNode[Any]

Return the last TreeNode in the directory.

has_children() → bool

Return whether this node has any children.

load_child_keys() → Sequence[Hashable]

Provide ParentNode with an ordered list of child keys (virtual function).

Raises:

TreeWidgetError – the subclass does not override this method.

load_child_node(key: Hashable) → TreeNode[Any]

Load the child node for a given key (virtual function).

Raises:

TreeWidgetError – the subclass does not override this method.

next_child(key: Hashable) → TreeNode[Any] | None

Return the next child node in index order from the given key.

prev_child(key: Hashable) → TreeNode[Any] | None

Return the previous child node in index order from the given key.

set_child_node(key: Hashable, node: TreeNode[Any]) → None

Set the child node for a given key.

Useful for bottom-up, lazy population of a tree.