TabbedContent¶
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 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 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 TabPane
s.
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:
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.
from textual.app import App, ComposeResult
from textual.widgets import Footer, Label, Markdown, TabbedContent, TabPane
LETO = """
# Duke Leto I Atreides
Head of House Atreides.
"""
JESSICA = """
# Lady Jessica
Bene Gesserit and concubine of Leto, and mother of Paul and Alia.
"""
PAUL = """
# Paul Atreides
Son of Leto and Jessica.
"""
class TabbedApp(App):
"""An example of tabbed content."""
BINDINGS = [
("l", "show_tab('leto')", "Leto"),
("j", "show_tab('jessica')", "Jessica"),
("p", "show_tab('paul')", "Paul"),
]
def compose(self) -> ComposeResult:
"""Compose app with tabbed content."""
# Footer to show keys
yield Footer()
# Add the TabbedContent widget
with TabbedContent(initial="jessica"):
with TabPane("Leto", id="leto"): # First tab
yield Markdown(LETO) # Tab content
with TabPane("Jessica", id="jessica"):
yield Markdown(JESSICA)
with TabbedContent("Paul", "Alia"):
yield TabPane("Paul", Label("First child"))
yield TabPane("Alia", Label("Second child"))
with TabPane("Paul", id="paul"):
yield Markdown(PAUL)
def action_show_tab(self, tab: str) -> None:
"""Switch to a new tab."""
self.get_child_by_type(TabbedContent).active = tab
if __name__ == "__main__":
app = TabbedApp()
app.run()
Styling¶
The TabbedContent
widget is composed of two main sub-widgets: a
Tabs
and a ContentSwitcher
; you can
style them accordingly.
The tabs within the Tabs
widget will have prefixed IDs; each ID being the
ID of the TabPane
the Tab
is for, prefixed with --content-tab-
. If you
wish to style individual tabs within the TabbedContent
widget you will
need to use that prefix for the Tab
IDs.
For example, to create a TabbedContent
that has red and green labels:
from textual.app import App, ComposeResult
from textual.widgets import Label, TabbedContent, TabPane
class ColorTabsApp(App):
CSS = """
TabbedContent #--content-tab-green {
color: green;
}
TabbedContent #--content-tab-red {
color: red;
}
"""
def compose(self) -> ComposeResult:
with TabbedContent():
with TabPane("Red", id="red"):
yield Label("Red!")
with TabPane("Green", id="green"):
yield Label("Green!")
if __name__ == "__main__":
ColorTabsApp().run()
Reactive Attributes¶
Name | Type | Default | Description |
---|---|---|---|
active |
str |
"" |
The id attribute of the active tab. Set this to switch tabs. |
Messages¶
Bindings¶
This widget has no bindings.
Component Classes¶
This widget has no component classes.
See also¶
Bases: Widget
A container with associated tabs to toggle content visibility.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
|
TextType
|
Positional argument will be used as title. |
()
|
|
str
|
The id of the initial tab, or empty string to select the first tab. |
''
|
|
str | None
|
The name of the tabbed content. |
None
|
|
str | None
|
The ID of the tabbed content in the DOM. |
None
|
|
str | None
|
The CSS classes of the tabbed content. |
None
|
|
bool
|
Whether the tabbed content is disabled or not. |
False
|
active
class-attribute
instance-attribute
¶
The ID of the active tab, or empty string if none are active.
Cleared
¶
Cleared(tabbed_content)
Bases: Message
Posted when no tab pane is active.
This can happen if all tab panes are removed or if the currently active tab pane is unset.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
|
TabbedContent
|
The TabbedContent widget. |
required |
control
property
¶
The TabbedContent
widget that was cleared of all tab panes.
This is an alias for Cleared.tabbed_content
and is used by the on
decorator.
tabbed_content
instance-attribute
¶
tabbed_content = tabbed_content
The TabbedContent
widget that contains the tab activated.
TabActivated
¶
TabActivated(tabbed_content, tab)
Bases: Message
Posted when the active tab changes.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
|
TabbedContent
|
The TabbedContent widget. |
required |
|
ContentTab
|
The Tab widget that was selected (contains the tab label). |
required |
ALLOW_SELECTOR_MATCH
class-attribute
instance-attribute
¶
Additional message attributes that can be used with the on
decorator.
control
property
¶
The TabbedContent
widget that contains the tab activated.
This is an alias for TabActivated.tabbed_content
and is used by the on
decorator.
pane
instance-attribute
¶
pane = get_pane(tab)
The TabPane
widget that was activated by selecting the tab.
tabbed_content
instance-attribute
¶
tabbed_content = tabbed_content
The TabbedContent
widget that contains the tab activated.
add_pane
¶
Add a new pane to the tabbed content.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
|
TabPane
|
The pane to add. |
required |
|
TabPane | str | None
|
Optional pane or pane ID to add the pane before. |
None
|
|
TabPane | str | None
|
Optional pane or pane ID to add the pane after. |
None
|
Returns:
Type | Description |
---|---|
AwaitComplete
|
An optionally awaitable object that waits for the pane to be added. |
Raises:
Type | Description |
---|---|
TabError
|
If there is a problem with the addition request. |
Note
Only one of before
or after
can be provided. If both are
provided an exception is raised.
clear_panes
¶
Remove all the panes in the tabbed content.
Returns:
Type | Description |
---|---|
AwaitComplete
|
An optionally awaitable object which waits for all panes to be removed and the Cleared message to be posted. |
get_pane
¶
get_pane(pane_id)
Get the TabPane
associated with the given ID or tab.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
|
str | ContentTab
|
The ID of the pane to get, or the Tab it is associated with. |
required |
Returns:
Type | Description |
---|---|
TabPane
|
The |
Raises:
Type | Description |
---|---|
ValueError
|
Raised if no ID was available. |
get_tab
¶
get_tab(pane_id)
Get the Tab
associated with the given ID or TabPane
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
|
str | TabPane
|
The ID of the pane, or the pane itself. |
required |
Returns:
Type | Description |
---|---|
Tab
|
The Tab associated with the ID. |
Raises:
Type | Description |
---|---|
ValueError
|
Raised if no ID was available. |
remove_pane
¶
remove_pane(pane_id)
Remove a given pane from the tabbed content.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
|
str
|
The ID of the pane to remove. |
required |
Returns:
Type | Description |
---|---|
AwaitComplete
|
An optionally awaitable object that waits for the pane to be removed and the Cleared message to be posted. |
Bases: Widget
A container for switchable content, with additional title.
This widget is intended to be used with TabbedContent.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
|
TextType
|
Title of the TabPane (will be displayed in a tab label). |
required |
|
Widget
|
Widget to go inside the TabPane. |
()
|
|
str | None
|
Optional name for the TabPane. |
None
|
|
str | None
|
Optional ID for the TabPane. |
None
|
|
str | None
|
Optional initial classes for the widget. |
None
|
|
bool
|
Whether the TabPane is disabled or not. |
False
|