diff options
author | Toshio Kuratomi <a.badger@gmail.com> | 2017-01-21 14:47:14 -0800 |
---|---|---|
committer | Toshio Kuratomi <a.badger@gmail.com> | 2017-01-21 16:28:48 -0800 |
commit | 4f85c63becc3267241b5940b32ed586a4da304a9 (patch) | |
tree | 4dd53376aa03704e071c7f0996662fb0d373cf23 | |
parent | cad6c144bf9940aa672611a36f2174655c579af7 (diff) | |
download | urwid-4f85c63becc3267241b5940b32ed586a4da304a9.tar.gz |
Implement postchange signal for Edit widget.
The Edit widget in 1.3.0 has a "change" signal which fires before the
edit_text is updated. This means that change signal handlers cannot
update the edit_text; the text is updated by the signal emitter after
the change handler has finished running. To remedy this, in a backwards
compatible way, create a second signal, "postchange" which fires after
edit_text has been changed. "postchange" sends the widget's old text
value as a parameter so that change handlers can use the former value
if needed (for instance, to revert a change because the new_text was
invalid)
-rw-r--r-- | urwid/widget.py | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/urwid/widget.py b/urwid/widget.py index a3e39d8..945a77f 100644 --- a/urwid/widget.py +++ b/urwid/widget.py @@ -1101,11 +1101,22 @@ class Edit(Text): deletion. A caption may prefix the editing area. Uses text class for text layout. - Users of this class to listen for ``"change"`` events - sent when the value of edit_text changes. See :func:``connect_signal``. + Users of this class may listen for ``"change"`` or ``"postchange"`` + events. See :func:``connect_signal``. + + * ``"change"`` is sent just before the value of edit_text changes. + It receives the new text as an argument. Note that ``"change"`` cannot + change the text in question as edit_text changes the text afterwards. + * ``"postchange"`` is sent after the value of edit_text changes. + It receives the old value of the text as an argument and thus is + appropriate for changing the text. It is possible for a ``"postchange"`` + event handler to get into a loop of changing the text and then being + called when the event is re-emitted. It is up to the event + handler to guard against this case (for instance, by not changing the + text if it is signaled for for text that it has already changed once). """ # (this variable is picked up by the MetaSignals metaclass) - signals = ["change"] + signals = ["change", "postchange"] def valid_char(self, ch): """ @@ -1160,6 +1171,7 @@ class Edit(Text): self.allow_tab = allow_tab self._edit_pos = 0 self.set_caption(caption) + self._edit_text = '' self.set_edit_text(edit_text) if edit_pos is None: edit_pos = len(edit_text) @@ -1354,10 +1366,12 @@ class Edit(Text): """ text = self._normalize_to_caption(text) self.highlight = None + self._emit("change", text) + old_text = self._edit_text self._edit_text = text if self.edit_pos > len(text): self.edit_pos = len(text) - self._emit("change", text) + self._emit("postchange", old_text) self._invalidate() def get_edit_text(self): |