Add Widget.remove_children method (#2657)

This commit is contained in:
darrenburns
2023-05-29 18:03:42 +01:00
committed by GitHub
parent ca17d8194e
commit 3e7b2c53a8
3 changed files with 54 additions and 4 deletions

View File

@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `work` decorator accepts `description` parameter to add debug string https://github.com/Textualize/textual/issues/2597
- Added `SelectionList` widget https://github.com/Textualize/textual/pull/2652
- `App.AUTO_FOCUS` to set auto focus on all screens https://github.com/Textualize/textual/issues/2594
- Added `Widget.remove_children` https://github.com/Textualize/textual/pull/2657
### Changed

View File

@@ -2919,6 +2919,15 @@ class Widget(DOMNode):
await_remove = self.app._remove_nodes([self], self.parent)
return await_remove
def remove_children(self) -> AwaitRemove:
"""Remove all children of this Widget from the DOM.
Returns:
An awaitable object that waits for the children to be removed.
"""
await_remove = self.app._remove_nodes(list(self.children), self)
return await_remove
def render(self) -> RenderableType:
"""Get renderable for widget.

View File

@@ -1,9 +1,9 @@
import asyncio
from textual.app import App
from textual.containers import Container
from textual.app import App, ComposeResult
from textual.containers import Container, Vertical
from textual.widget import Widget
from textual.widgets import Button, Static
from textual.widgets import Button, Label, Static
async def test_remove_single_widget():
@@ -117,3 +117,43 @@ async def test_query_remove_order():
await pilot.app.query(Removable).remove()
assert len(pilot.app.screen.walk_children(with_self=False)) == 0
assert removals == ["grandchild", "child", "parent"]
class ExampleApp(App):
def compose(self) -> ComposeResult:
yield Button("ABC")
yield Label("Outside of vertical.")
with Vertical():
for index in range(5):
yield Label(str(index))
async def test_widget_remove_children_container():
app = ExampleApp()
async with app.run_test():
container = app.query_one(Vertical)
# 6 labels in total, with 5 of them inside the container.
assert len(app.query(Label)) == 6
assert len(container.children) == 5
await container.remove_children()
# The labels inside the container are gone, and the 1 outside remains.
assert len(app.query(Label)) == 1
assert len(container.children) == 0
async def test_widget_remove_children_no_children():
app = ExampleApp()
async with app.run_test():
button = app.query_one(Button)
count_before = len(app.query("*"))
await button.remove_children()
count_after = len(app.query("*"))
assert len(app.query(Button)) == 1 # The button still remains.
assert (
count_before == count_after
) # No widgets have been removed, since Button has no children.