Skip to content

Commit 2f86ee4

Browse files
authored
Allow setting a toggle button's label (#3765)
* Allow setting a toggle button's label Until now CheckBox and RadioButton labels have been fixed after the widgets have been created. Prompted by #3764 and seeing no reasonable reason to not allow updating the labels later on, this adds that ability. * Link the CHANGELOG entries to the PR * Ensure the setter enforces the first-line-only rule too
1 parent 4058e59 commit 2f86ee4

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1919
- Added experimental Canvas class https://github.com/Textualize/textual/pull/3669/
2020
- Added `keyline` rule https://github.com/Textualize/textual/pull/3669/
2121
- Widgets can now have an ALLOW_CHILDREN (bool) classvar to disallow adding children to a widget https://github.com/Textualize/textual/pull/3758
22+
- Added the ability to set the `label` property of a `Checkbox` https://github.com/Textualize/textual/pull/3765
23+
- Added the ability to set the `label` property of a `RadioButton` https://github.com/Textualize/textual/pull/3765
2224

2325
### Changed
2426

src/textual/widgets/_toggle_button.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,18 +149,35 @@ def __init__(
149149
# NOTE: Don't send a Changed message in response to the initial set.
150150
with self.prevent(self.Changed):
151151
self.value = value
152-
self._label = Text.from_markup(label) if isinstance(label, str) else label
152+
self._label = self._make_label(label)
153+
154+
def _make_label(self, label: TextType) -> Text:
155+
"""Make a `Text` label from a `TextType` value.
156+
157+
Args:
158+
label: The source value for the label.
159+
160+
Returns:
161+
A `Text` rendering of the label for use in the button.
162+
"""
163+
label = Text.from_markup(label) if isinstance(label, str) else label
153164
try:
154165
# Only use the first line if it's a multi-line label.
155-
self._label = self._label.split()[0]
166+
label = label.split()[0]
156167
except IndexError:
157168
pass
169+
return label
158170

159171
@property
160172
def label(self) -> Text:
161173
"""The label associated with the button."""
162174
return self._label
163175

176+
@label.setter
177+
def label(self, label: TextType) -> None:
178+
self._label = self._make_label(label)
179+
self.refresh(layout=True)
180+
164181
@property
165182
def _button(self) -> Text:
166183
"""The button, reflecting the current value."""

tests/toggles/test_labels.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""Test that setting a toggle button's label has the desired effect."""
2+
3+
from rich.text import Text
4+
5+
from textual.app import App, ComposeResult
6+
from textual.widgets import Checkbox, RadioButton, RadioSet
7+
8+
9+
class LabelChangeApp(App[None]):
10+
def compose(self) -> ComposeResult:
11+
yield Checkbox("Before")
12+
yield RadioButton("Before")
13+
yield RadioSet("Before")
14+
15+
16+
async def test_change_labels() -> None:
17+
"""It should be possible to change the labels of toggle buttons."""
18+
async with LabelChangeApp().run_test() as pilot:
19+
assert pilot.app.query_one(Checkbox).label == Text("Before")
20+
assert pilot.app.query_one("Screen > RadioButton", RadioButton).label == Text(
21+
"Before"
22+
)
23+
assert pilot.app.query_one("RadioSet > RadioButton", RadioButton).label == Text(
24+
"Before"
25+
)
26+
pilot.app.query_one(Checkbox).label = "After"
27+
pilot.app.query_one("Screen > RadioButton", RadioButton).label = "After"
28+
pilot.app.query_one("RadioSet > RadioButton", RadioButton).label = "After"
29+
await pilot.pause()
30+
assert pilot.app.query_one(Checkbox).label == Text("After")
31+
assert pilot.app.query_one("Screen > RadioButton", RadioButton).label == Text(
32+
"After"
33+
)
34+
assert pilot.app.query_one("RadioSet > RadioButton", RadioButton).label == Text(
35+
"After"
36+
)

0 commit comments

Comments
 (0)