Textual 101 – Using the TabbedContent Widget

Textual is a text-based user interface library (TUI) for the Python programming language. With Textual, you can create beautiful cross-platform TUI applications.

If you would like more information, see An Intro to Textual – Creating Text User Interfaces with Python

In this article, you will learn how to created a tabbed interface in your terminal using Textual. Some other GUI toolkits called tabbed interfaces “pages” or “notebooks”. But in Textual-land, it is called TabbedContent!

The TabbedContent Widget

Let’s take a look at how you can add tabbed content to your terminal GUI / TUI.

Open up your favorite Python editor and create a file named tabbed_demo.py or give it your own memorable name.

Then enter the following code:

# tabbed_demo.py

from textual.app import App, ComposeResult
from textual.widgets import Button, Markdown, TabbedContent

PYTHON = """
# Python - An Amazing Language

You should use Python!

## Features

- Easy and readable
- Can run almost anywhere
- Python is fast enough
"""

C = """
# C++ - When You Want FAST

Fast but harder to learn than Python

## Features

- Stupid fast
- Harder to code
- Makes small exes
"""

RUBY = """
# Ruby - A Web Language

Expressive and versatile

## Features

- Has a popular web framework
- Interpretive
"""

class TabbedDemo(App):

    def compose(self) -> ComposeResult:
        self.close_button = Button("Close", id="close")
        
        tabs = ("Python", "C++", "Ruby")
        
        with TabbedContent(*tabs):
            yield Markdown(PYTHON)
            yield Markdown(C)
            yield Markdown(RUBY)
            
        yield self.close_button
        
    def on_mount(self) -> None:
        self.screen.styles.background = "darkblue"
        self.close_button.styles.background = "red"

    def on_button_pressed(self, event: Button.Pressed) -> None:
        self.exit(event.button.id)

if __name__ == "__main__":
    app = TabbedDemo()
    app.run()

The first two lines of code are your Textual imports for the various bits you’ll need to create your user interface. Then you create three constants that hold multi-line strings. The multi-line strings contain Markdown, which is a type of markup that is used often on GitHub for documentation purposes.

Textual has a Markdown widget which will transform the multi-line strings into a nicely formatted page of text. To create the “pages” or “tabs” of content, you use TabbedContent as a content manager via Python’s with statement. You pass in the labels for each tab using a tuple.

Note that to get the tabs inserted correctly, you need to use an asterisk when passing in the tuple to TabbedContent.

The rest of the code is pretty self-explanatory if you have read the introductory article linked at the beginning of this tutorial.

When you run this code, you will see something like the following:

Textual demo app with TabbedContent

Wrapping Up

The TabbedContent widget is a really nice way to add tabbed content to your text-based user interface. Give it a try using some of Textual’s other widgets and see for yourself!

Related Articles