summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Stepanov <penguinolog@users.noreply.github.com>2023-05-05 14:37:58 +0200
committerGitHub <noreply@github.com>2023-05-05 14:37:58 +0200
commitd26cb42a9fd28cb0743ad04d5ed2a0c7f28b89e3 (patch)
treed76f6592bebd2155fea97d20dd596a36170d7158
parentabc098c3400220b51aeb6fec14175e1bfa1f8bfb (diff)
downloadurwid-d26cb42a9fd28cb0743ad04d5ed2a0c7f28b89e3.tar.gz
Fix CheckBox default state validation and initialization (#553)
Fix #552 Co-authored-by: Aleksei Stepanov <alekseis@nvidia.com>
-rwxr-xr-xurwid/wimp.py48
1 files changed, 29 insertions, 19 deletions
diff --git a/urwid/wimp.py b/urwid/wimp.py
index d0037af..5ec0225 100755
--- a/urwid/wimp.py
+++ b/urwid/wimp.py
@@ -118,7 +118,8 @@ class CheckBox(WidgetWrap):
states = {
True: SelectableIcon("[X]", 1),
False: SelectableIcon("[ ]", 1),
- 'mixed': SelectableIcon("[#]", 1) }
+ 'mixed': SelectableIcon("[#]", 1)
+ }
reserve_columns = 4
# allow users of this class to listen for change events
@@ -154,36 +155,48 @@ class CheckBox(WidgetWrap):
urwid.disconnect_signal(check_box, 'change', callback, user_data)
- >>> CheckBox(u"Confirm")
+ >>> CheckBox("Confirm")
<CheckBox selectable flow widget 'Confirm' state=False>
- >>> CheckBox(u"Yogourt", "mixed", True)
+ >>> CheckBox("Yogourt", "mixed", True)
<CheckBox selectable flow widget 'Yogourt' state='mixed'>
- >>> cb = CheckBox(u"Extra onions", True)
+ >>> cb = CheckBox("Extra onions", True)
>>> cb
<CheckBox selectable flow widget 'Extra onions' state=True>
- >>> cb.render((20,), focus=True).text # ... = b in Python 3
- [...'[X] Extra onions ']
+ >>> cb.render((20,), focus=True).text
+ [b'[X] Extra onions ']
+ >>> CheckBox("Test", None)
+ Traceback (most recent call last):
+ ...
+ ValueError: None not in (True, False, 'mixed')
"""
- super().__init__(None) # self.w set by set_state below
- self._label = Text("")
+ if state not in self.states:
+ raise ValueError(f"{state!r} not in {tuple(self.states.keys())}")
+
+ self._label = Text(label)
self.has_mixed = has_mixed
- self._state = None
+
+ self._state = state
if checked_symbol:
self.states[True] = SelectableIcon(f"[{checked_symbol}]", 1)
# The old way of listening for a change was to pass the callback
# in to the constructor. Just convert it to the new way:
if on_state_change:
connect_signal(self, 'change', on_state_change, user_data)
- self.set_label(label)
- self.set_state(state)
+
+ # Initial create expect no callbacks call, create explicit
+ super().__init__(
+ Columns(
+ [('fixed', self.reserve_columns, self.states[state]), self._label],
+ focus_column=0,
+ ),
+ )
def _repr_words(self):
return super()._repr_words() + [
repr(self.label)]
def _repr_attrs(self):
- return dict(super()._repr_attrs(),
- state=self.state)
+ return dict(super()._repr_attrs(), state=self.state)
def set_label(self, label):
"""
@@ -257,15 +270,12 @@ class CheckBox(WidgetWrap):
# self._state is None is a special case when the CheckBox
# has just been created
old_state = self._state
- if do_callback and old_state is not None:
+ if do_callback:
self._emit('change', state)
self._state = state
# rebuild the display widget with the new state
- self._w = Columns( [
- ('fixed', self.reserve_columns, self.states[state] ),
- self._label ] )
- self._w.focus_col = 0
- if do_callback and old_state is not None:
+ self._w = Columns([('fixed', self.reserve_columns, self.states[state]), self._label], focus_column=0)
+ if do_callback:
self._emit('postchange', old_state)
def get_state(self) -> bool | Literal['mixed']: