The latest version of Urwid in subversion now incorporates a new caching
mechanism and a compiled C version of some string utilities from Rebecca
Breu.
The performance has really improved since the last stable release
(0.9.7.2). Here are the results I get when comparing the two versions
running the benchmark programs in contrib:
: reduction in running time / speed improvement
bench_1.py (tour): 41% / 70%
bench_2.py (bigtext): 82% / 450%
bench_3.py (calc): 56% / 125%
bench_4.py (graph): 73% / 268%
Some further improvements are still possible, but the latest version is
very close to what will be released as 0.9.8.
Now to the changes.
All the standard widgets in Urwid now cache the canvas they produce from
their render() functions. The caching is done using a new CanvasCache
class. The CanvasCache will hold on to a canvas as long as there is
still a reference to it. The Screen objects in raw_display and
curses_display hold on to a reference to the last screen rendered,
allowing the cache to work without modifying your applications.
However, caching canvases requires that we know when a widget has
changed, so there are a couple changes to Urwid's interface that I
couldn't avoid.
Pile and Columns widgets need to know when their content changes, so
while you used to be able to write code like:
some_widgets = [widget_a, widget_b, widget_c]
piled_widgets = urwid.Pile(some_widgets)
# later add/remove items from some_widgets
Now you will have to write:
piled_widgets = urwid.Pile([widget_a, widget_b, widget_c])
some_widgets = piled_widgets.widget_list
# later add/remove items from some_widgets
This change is backwards-compatible with earlier versions of Urwid. Now
the widget_list member of Pile and Columns is a special list type that
can detect changes to its contents.
The ListBox class delegates determining what widgets are displayed to a
"list walker". The default list walker class can now detect changes in
the same way that Pile and Columns do. If you are using code similar to:
some_widgets = [widget_a, widget_b, widget_c]
listbox = urwid.ListBox(some_widgets)
# later add/remove items from some_widgets
Now you will have to write:
listbox = urwid.ListBox([widget_a, widget_b, widget_c])
some_widgets = urwid.ListBox.body
# later add/remove items from some_widgets
This change is also backwards compatible.
Custom list walker classes now need to support sending a "modified"
signal when their contents change. A list walker class might have
looked like:
class CustomListWalker(object):
# definitions of get_focus, set_focus, get_next, get_prev...
Now you will have to write:
class CustomListWalker(urwid.ListWalker):
# definitions of get_focus, set_focus, get_next, get_prev...
# call self._modified() when the contents change.
Or, if you need to have backwards compatibility write:
try: ListWalker = urwid.ListWalker
except:
class ListWalker(object):
def _modified(self): pass
class CustomListWalker(ListWalker):
# definitions of get_focus, set_focus, get_next, get_prev...
# call self._modified() when the contents change.
Please post to this list or join our IRC channel if you have any
questions or comments.
Ian
_______________________________________________
Urwid mailing list
[email protected]
http://lists.excess.org/mailman/listinfo/urwid