Textual – Switching Screens in Your Terminal

The Screen is a container for your widgets. These screens occupy the dimensions of your terminal by default. While you can have many different screens in a single application, only one screen may be active at a time.

When you create your App class, Textual will create a screen object implicitly. Yes, Textual requires you to have at least one screen or your application won’t work. If you do not create a new screen or switch to a different one, the default screen is where your widgets will get mounted or composed to.

Screens are a great way to organize your application. Many applications have settings pages, help pages, and more. These are just a few examples of how you can use screens.

Now that you know what a screen is, you’re ready to learn how to create new ones!

Creating Screens

When you create an application, you create a Screen implicitly. But how do you create your own Screen? Fortunately, Textual has made that easy. All you need to do is import the Screen class from textual.screen and extend it as needed.

You can style screens the same way you do other widgets, except for the dimensions as screens are always the same size as your terminal window.

To see how this all works, you will create an application with two screens:

  • Your main screen
  • You second screen, which will be green

You will be able to switch between the screens using a button. Each screen has its own button and its own event or message handler.

Open up your favorite Python IDE and create a new file called two_screens.py with the following contents:

# two_screens.py

from textual import on
from textual.app import App, ComposeResult
from textual.screen import Screen
from textual.widgets import Button

class GreenScreen(Screen):

    def compose(self) -> ComposeResult:
        self.styles.background = "green"
        yield Button("Main Screen", id="main")

    @on(Button.Pressed, "#main")
    def on_main(self) -> None:
        self.dismiss()


class MainAop(App):

    def compose(self) -> ComposeResult:
        yield Button("Switch", id="switch")

    @on(Button.Pressed, "#switch")
    def on_switch(self) -> None:
        self.push_screen(GreenScreen())


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

You use Textual’s handy on decorator to match against the button’s id. That keeps the message from bubbling around to other event handlers, which is what could happen if you had used on_button_pressed(), for example.

When you run your application, you will see something like this:

Textual screens

Try clicking the buttons and switching between the screens.

Of course, you don’t need to use button’s at all, if you don’t want to. You could use keyboard shortcuts instead. Why not give that a try?

Go back to your Python IDE and create a new file called two_screens_keys_only.py with this code in it:

# two_screens_keys_only.py

from textual.app import App, ComposeResult
from textual.screen import Screen
from textual.widgets import Label


class GreenScreen(Screen):
    BINDINGS = [("escape", "app.pop_screen", "Dismiss the screen")]

    def compose(self) -> ComposeResult:
        self.styles.background = "green"
        yield Label("Second Screen")


class MainAop(App):
    SCREENS = {"green": GreenScreen}
    BINDINGS = [("n", "push_screen('green')", "Green Screen")]

    def compose(self) -> ComposeResult:
        yield Label("Main screen")


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

Using keyboard shortcuts makes your code a little less verbose. However, since you aren’t using a Footer widget, the shortcuts are not shown on-screen to the user. When you are on the main screen, you must press the letter “n” on your keyboard to switch to the GreenScreen. Then when you want to switch back, you press “Esc” or escape.

Here’s what the screen looks like on the GreenScreen:

Textual screens using keyboard shortcuts

Now try using the keys mentioned to swap between the two screens. Feel free to change the keyboard bindings to keys of your own choosing.

Wrapping Up

Textual can do much more with Screens than what is covered in this brief tutorial. However, you can use this information as a great starting point for learning how to add one more additional screens to your GUI in your terminal.

Play around with these examples and then run over to the Textual documentation to learn about some of the other widgets you can add to bring your application to life.

Want to Learn More?

If you’d like to learn more about Textual, check out my book: Creating TUI Applications with Textual and Python, which you can find on the following websites:

Creating TUI Applications with Textual and Python (paperback)