Files
textual/docs/widgets/tabbed_content.md
darrenburns f95e30870b Tabbed content activated message (#2260)
* Add a message for the tabbed content activated

* Add a docstring

* Testing tabbed content activated message

* Update changelog

* Add reference to the docs about TabbedContent.TabActivated
2023-04-12 10:55:14 +01:00

3.3 KiB

TabbedContent

!!! tip "Added in version 0.16.0"

Switch between mutually exclusive content panes via a row of tabs.

  • Focusable
  • Container

This widget combines the Tabs and ContentSwitcher widgets to create a convenient way of navigating content.

Only a single child of TabbedContent is visible at once. Each child has an associated tab which will make it visible and hide the others.

Composing

There are two ways to provide the titles for the tab. You can pass them as positional arguments to the [TabbedContent][textual.widgets.TabbedContent] constructor:

def compose(self) -> ComposeResult:
    with TabbedContent("Leto", "Jessica", "Paul"):
        yield Markdown(LETO)
        yield Markdown(JESSICA)
        yield Markdown(PAUL)

Alternatively you can wrap the content in a [TabPane][textual.widgets.TabPane] widget, which takes the tab title as the first parameter:

def compose(self) -> ComposeResult:
    with TabbedContent():
        with TabPane("Leto"):
            yield Markdown(LETO)
        with TabPane("Jessica"):
            yield Markdown(JESSICA)
        with TabPane("Paul"):
            yield Markdown(PAUL)

Switching tabs

If you need to programmatically switch tabs, you should provide an id attribute to the TabPanes.

def compose(self) -> ComposeResult:
    with TabbedContent():
        with TabPane("Leto", id="leto"):
            yield Markdown(LETO)
        with TabPane("Jessica", id="jessica"):
            yield Markdown(JESSICA)
        with TabPane("Paul", id="paul"):
            yield Markdown(PAUL)

You can then switch tabs by setting the active reactive attribute:

# Switch to Jessica tab
self.query_one(TabbedContent).active = "jessica"

!!! note

If you don't provide `id` attributes to the tab panes, they will be assigned sequentially starting at `tab-1` (then `tab-2` etc).

Initial tab

The first child of TabbedContent will be the initial active tab by default. You can pick a different initial tab by setting the initial argument to the id of the tab:

def compose(self) -> ComposeResult:
    with TabbedContent(initial="jessica"):
        with TabPane("Leto", id="leto"):
            yield Markdown(LETO)
        with TabPane("Jessica", id="jessica"):
            yield Markdown(JESSICA)
        with TabPane("Paul", id="paul"):
            yield Markdown(PAUL)

Example

The following example contains a TabbedContent with three tabs.

=== "Output"

```{.textual path="docs/examples/widgets/tabbed_content.py"}
```

=== "tabbed_content.py"

```python
--8<-- "docs/examples/widgets/tabbed_content.py"
```

Reactive attributes

Name Type Default Description
active str "" The id attribute of the active tab. Set this to switch tabs.

Messages

  • [TabbedContent.TabActivated][textual.widgets.TabbedContent.TabActivated]

See also


::: textual.widgets.TabbedContent options: heading_level: 2


::: textual.widgets.TabPane options: heading_level: 2