diff --git a/docs/examples/guide/layout/combining_layouts.py b/docs/examples/guide/layout/combining_layouts.py index d832bd628..c52ecce0d 100644 --- a/docs/examples/guide/layout/combining_layouts.py +++ b/docs/examples/guide/layout/combining_layouts.py @@ -1,6 +1,6 @@ +from textual.app import App, ComposeResult from textual.containers import Container, Horizontal, Vertical -from textual.app import ComposeResult, App -from textual.widgets import Static, Header +from textual.widgets import Header, Static class CombiningLayoutsExample(App): @@ -8,28 +8,21 @@ class CombiningLayoutsExample(App): def compose(self) -> ComposeResult: yield Header() - yield Container( - Vertical( - *[Static(f"Vertical layout, child {number}") for number in range(15)], - id="left-pane", - ), - Horizontal( - Static("Horizontally"), - Static("Positioned"), - Static("Children"), - Static("Here"), - id="top-right", - ), - Container( - Static("This"), - Static("panel"), - Static("is"), - Static("using"), - Static("grid layout!", id="bottom-right-final"), - id="bottom-right", - ), - id="app-grid", - ) + with Container(id="app-grid"): + with Vertical(id="left-pane"): + for number in range(15): + yield Static(f"Vertical layout, child {number}") + with Horizontal(id="top-right"): + yield Static("Horizontally") + yield Static("Positioned") + yield Static("Children") + yield Static("Here") + with Container(id="bottom-right"): + yield Static("This") + yield Static("panel") + yield Static("is") + yield Static("using") + yield Static("grid layout!", id="bottom-right-final") if __name__ == "__main__": diff --git a/docs/examples/guide/layout/utility_containers_using_with.py b/docs/examples/guide/layout/utility_containers_using_with.py new file mode 100644 index 000000000..d09a3481e --- /dev/null +++ b/docs/examples/guide/layout/utility_containers_using_with.py @@ -0,0 +1,21 @@ +from textual.app import App, ComposeResult +from textual.containers import Horizontal, Vertical +from textual.widgets import Static + + +class UtilityContainersExample(App): + CSS_PATH = "utility_containers.css" + + def compose(self) -> ComposeResult: + with Horizontal(): + with Vertical(classes="column"): + yield Static("One") + yield Static("Two") + with Vertical(classes="column"): + yield Static("Three") + yield Static("Four") + + +if __name__ == "__main__": + app = UtilityContainersExample() + app.run() diff --git a/docs/guide/layout.md b/docs/guide/layout.md index 94405d837..3fe1184e0 100644 --- a/docs/guide/layout.md +++ b/docs/guide/layout.md @@ -159,7 +159,50 @@ In other words, we have a single row containing two columns. ``` You may be tempted to use many levels of nested utility containers in order to build advanced, grid-like layouts. -However, Textual comes with a more powerful mechanism for achieving this known as _grid layout_, which we'll discuss next. +However, Textual comes with a more powerful mechanism for achieving this known as _grid layout_, which we'll discuss below. + +## Composing with context managers + +In the previous section we've show how you add children to a container (such as `Horizontal` and `Vertical`) using positional arguments. +It's fine to do it this way, but Textual offers a simplified syntax using [context managers](https://docs.python.org/3/reference/datamodel.html#context-managers) which is generally easier to write and edit. + +When composing a widget, you can introduce a container using Python's `with` statement. +Any widgets yielded within that block are added as a child of the container. + +Let's update the [utility containers](#utility-containers) example to use the context manager approach. + +=== "utility_containers_using_with.py" + + !!! note + + This code uses context managers to compose widgets. + + ```python hl_lines="10-16" + --8<-- "docs/examples/guide/layout/utility_containers_using_with.py" + ``` + +=== "utility_containers.py" + + !!! note + + This is the original code using positional arguments. + + ```python hl_lines="10-21" + --8<-- "docs/examples/guide/layout/utility_containers.py" + ``` + +=== "utility_containers.css" + + ```sass + --8<-- "docs/examples/guide/layout/utility_containers.css" + ``` + +=== "Output" + + ```{.textual path="docs/examples/guide/layout/utility_containers_using_with.py"} + ``` + +Note how the end result is the same, but the code with context managers is a little easer to read. It is up to you which method you want to use, and you can mix context managers with positional arguments if you like! ## Grid