Build a Textual TUI App Skeleton in Python
Create a minimal Textual terminal UI app with a header, label, button, and footer, ready for interactive mock demonstrations.
pip install textual
Python code
22 linesfrom textual.app import App, ComposeResult
from textual.widgets import Header, Footer, Button, Label
class MockApp(App):
"""A minimal Textual TUI app skeleton."""
BINDINGS = [("q", "quit", "Quit")]
def compose(self) -> ComposeResult:
"""Create child widgets."""
yield Header()
yield Label("Welcome to the mock app!")
yield Button("Press Me", id="press")
yield Footer()
def on_button_pressed(self, event: Button.Pressed) -> None:
"""Handle button clicks by updating the label."""
label = self.query_one(Label)
label.update(f"Button clicked!")
if __name__ == "__main__":
MockApp().run()
Output
Interactive terminal app. Displays header, 'Welcome to the mock app!', a 'Press Me' button (renders as a clickable box), and footer. Pressing 'q' or clicking the button quits or updates the label to 'Button clicked!'. Key presses show in the footer: 'q → Quit'.
How it works
The app defines a compose method that yields widgets in order: Header, Label, Button, and Footer. Textual's event system dispatches Button.Pressed to the matching on_button_pressed handler, where query_one(Label) finds the widget to update. The BINDINGS list registers the 'q' key to quit the app with a help hint in the footer. Running the app enters an event loop that renders the TUI and processes input until quit.
Common mistakes
- Importing from `textual.widget` instead of `textual.widgets`.
- Forgetting to call `await` on widget updates when using async handlers.
- Overriding `on_load`, `on_mount`, or `compose` incorrectly and shadowing built-in behavior.
- Not specifying `id` on widgets when using `query_one` with a type; it may match multiple instances.
Variations
- Run the app in test mode using `App.run_test()` for headless testing of widget interactions.
- Use `app.push_screen()` to switch between multiple screen layouts in a multi-page TUI.
Real-world use cases
- Build CLI configuration tools where users navigate and edit settings with keyboard and mouse.
- Create a lightweight data-entry form for internal ops dashboards that runs over SSH.
- Prototype a terminal-based log viewer with filters before hooking into a real log stream.
Sponsored
More from Modern tooling
- Build a Recipe Runner Mock in Python easy
- Configure ruff linter rules in pyproject.toml with Python easy
- Data Conversion Helper Functions in Python easy
- How to Bind and Mock structlog Context in Python medium
- How to Build a Chainable Filter Helper in Python easy
- How to Build a Wheel with Hatchling in Python easy
Keep learning
Related tutorials and quizzes for this topic.