Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/4631.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A failed `SplitContainer.content` assignment no longer orphans the currently-displayed widgets.
13 changes: 8 additions & 5 deletions core/src/toga/widgets/splitcontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,6 @@ def content(self) -> list[SplitContainerContentT]:

@content.setter
def content(self, content: Sequence[SplitContainerContentT]) -> None:
for old_content in self._content:
if old_content is not None:
old_content.app = None
old_content.window = None

try:
if len(content) != 2:
raise TypeError()
Expand Down Expand Up @@ -131,6 +126,14 @@ def content(self, content: Sequence[SplitContainerContentT]) -> None:
_content.append(widget)
flex.append(flex_value)

# Only detach the old content once the new content is fully validated,
# so a failed assignment doesn't orphan the widgets currently shown.
for old_content in self._content:
if old_content is not None:
old_content.app = None
old_content.window = None

for widget in _content:
if widget:
widget.app = self.app
widget.window = self.window
Expand Down
17 changes: 17 additions & 0 deletions core/tests/widgets/test_splitcontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,23 @@ def test_set_content_invalid(splitcontainer, content, message):
splitcontainer.content = content


def test_set_content_invalid_keeps_previous_content(content1, content2):
"""A failed content assignment must not orphan the widgets currently shown."""
app = toga.App("Test App", "org.beeware.toga.splitcontainer-test")
window = toga.Window()
splitcontainer = toga.SplitContainer(content=[content1, content2])
window.content = splitcontainer

assert content1.id in app.widgets

with pytest.raises(ValueError):
splitcontainer.content = [content1]

# The previous content is still attached and intact
assert content1.id in app.widgets
assert splitcontainer.content == [content1, content2]


def test_direction(splitcontainer):
"""The direction of the splitcontainer can be changed."""

Expand Down
Loading