diff options
author | exquo <62397152+exquo@users.noreply.github.com> | 2023-03-29 09:03:31 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-29 11:03:31 +0200 |
commit | ab23c8bea814cbbc17bf5ace66abd62ab4c34243 (patch) | |
tree | acef7d88b5c3b121e23947d359738eea87255f9f | |
parent | 9e7ec1c69d33c7b365b081ca72074e6c6979c85f (diff) | |
download | urwid-ab23c8bea814cbbc17bf5ace66abd62ab4c34243.tar.gz |
Reconnect the 'modified' signal after setting a new ListBox.body (#474)
Ensure that the cached canvas is marked invalidated when a newly set ListBox.body is modified at runtime.
Fixes #428
-rw-r--r-- | urwid/listbox.py | 21 | ||||
-rw-r--r-- | urwid/tests/test_listbox.py | 11 |
2 files changed, 24 insertions, 8 deletions
diff --git a/urwid/listbox.py b/urwid/listbox.py index fd4b117..e49edaa 100644 --- a/urwid/listbox.py +++ b/urwid/listbox.py @@ -27,7 +27,7 @@ from urwid.canvas import SolidCanvas, CanvasCombine from urwid.widget import Widget, nocache_widget_render_instance, BOX, GIVEN from urwid.decoration import calculate_top_bottom_filler, normalize_valign from urwid import signals -from urwid.signals import connect_signal +from urwid.signals import connect_signal, disconnect_signal from urwid.monitored_list import MonitoredList, MonitoredFocusList from urwid.container import WidgetContainerMixin from urwid.command_map import (CURSOR_UP, CURSOR_DOWN, @@ -250,13 +250,6 @@ class ListBox(Widget, WidgetContainerMixin): :type body: ListWalker """ self._set_body(body) - try: - connect_signal(self._body, "modified", self._invalidate) - except NameError: - # our list walker has no modified signal so we must not - # cache our canvases because we don't know when our - # content has changed - self.render = nocache_widget_render_instance(self) # offset_rows is the number of rows between the top of the view # and the top of the focused item @@ -281,10 +274,22 @@ class ListBox(Widget, WidgetContainerMixin): return self._body def _set_body(self, body): + try: + disconnect_signal(self._body, "modified", self._invalidate) + except AttributeError: + # _body is not yet assigned + pass if getattr(body, 'get_focus', None): self._body = body else: self._body = SimpleListWalker(body) + try: + connect_signal(self._body, "modified", self._invalidate) + except NameError: + # our list walker has no modified signal so we must not + # cache our canvases because we don't know when our + # content has changed + self.render = nocache_widget_render_instance(self) self._invalidate() body = property(_get_body, _set_body, doc=""" diff --git a/urwid/tests/test_listbox.py b/urwid/tests/test_listbox.py index adeb8d5..9d2eddb 100644 --- a/urwid/tests/test_listbox.py +++ b/urwid/tests/test_listbox.py @@ -802,3 +802,14 @@ class ZeroHeightContentsTest(unittest.TestCase): lb.keypress((40,10), 'up') self.assertEqual(lb.get_focus()[1], 1) + +class ListBoxSetBodyTest(unittest.TestCase): + def test_signal_connected(self): + lb = urwid.ListBox([]) + lb.body = urwid.SimpleListWalker([]) + self.assertEqual( + lb.body._urwid_signals['modified'][0][1], + lb._invalidate, + "outdated canvas cache reuse " + "after ListWalker's contents modified" + ) |