CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-textual

Modern Text User Interface framework for building cross-platform terminal and web applications with Python

Overall
score

93%

Overview
Eval results
Files

core-framework.mddocs/

Core Framework

Essential application framework components for building Textual applications, including the main App class, base Widget class, screen management, and decorators for event handling and background tasks.

Capabilities

Application Class

The App class is the foundation of every Textual application, managing the event loop, screen stack, styling, and overall application lifecycle.

class App:
    """
    The main application class.
    
    Generic type parameter for return value: App[ReturnType]
    """
    def __init__(self, **kwargs):
        """
        Initialize the application.
        
        Parameters:
        - css_path: str | list[str] - Path(s) to CSS files for styling
        - watch_css: bool - Automatically reload CSS files during development
        """
    
    def run(self) -> None:
        """Run the application synchronously."""
    
    async def run_async(self) -> None:
        """Run the application asynchronously."""
    
    def push_screen(self, screen: Screen) -> None:
        """
        Push a new screen onto the screen stack.
        
        Parameters:
        - screen: Screen instance to display
        """
    
    def pop_screen(self) -> Screen:
        """Pop the current screen from the stack and return it."""
    
    def exit(self, result=None) -> None:
        """
        Exit the application.
        
        Parameters:
        - result: Optional return value for the application
        """
    
    def compose(self) -> ComposeResult:
        """Compose the application's default screen widgets."""
    
    def on_mount(self) -> None:
        """Called when the application starts."""
    
    def on_ready(self) -> None:
        """Called when the application is ready to receive events."""
    
    # Properties
    screen_stack: list[Screen]
    title: str
    sub_title: str
    css_path: str | list[str] | None

Base Widget Class

The Widget class is the base for all UI components in Textual, providing composition, rendering, lifecycle management, and event handling capabilities.

class Widget:
    """
    Base class for all widgets.
    """
    def __init__(self, **kwargs):
        """
        Initialize the widget.
        
        Parameters:
        - name: str - Widget name for CSS targeting
        - id: str - Unique identifier for the widget
        - classes: str - CSS classes for styling
        - disabled: bool - Whether the widget is disabled
        """
    
    def compose(self) -> ComposeResult:
        """
        Compose child widgets.
        
        Returns:
        Iterator of child widgets
        """
    
    def render(self) -> RenderableType:
        """
        Render the widget content.
        
        Returns:
        Rich renderable object
        """
    
    def on_mount(self) -> None:
        """Called when widget is added to the DOM."""
    
    def on_unmount(self) -> None:
        """Called when widget is removed from the DOM."""
    
    def refresh(self, *, repaint: bool = True, layout: bool = False) -> None:
        """
        Refresh the widget.
        
        Parameters:
        - repaint: bool - Whether to repaint the widget
        - layout: bool - Whether to recalculate layout
        """
    
    def remove(self) -> None:
        """Remove the widget from its parent."""
    
    def focus(self, scroll_visible: bool = True) -> None:
        """
        Give focus to the widget.
        
        Parameters:
        - scroll_visible: bool - Scroll to make widget visible
        """
    
    def blur(self) -> None:
        """Remove focus from the widget."""
    
    def scroll_to(self, x: int = None, y: int = None, *, animate: bool = True) -> None:
        """
        Scroll to a position.
        
        Parameters:
        - x: int - X coordinate to scroll to
        - y: int - Y coordinate to scroll to  
        - animate: bool - Whether to animate the scroll
        """
    
    # Properties
    id: str | None
    name: str | None
    classes: set[str]
    disabled: bool
    parent: Widget | None
    children: list[Widget]
    styles: Styles
    has_focus: bool

Screen Management

Screen classes represent full-screen views that can be pushed onto a screen stack, enabling complex navigation patterns and modal dialogs.

class Screen:
    """
    A screen is a special widget that represents the entire terminal.
    
    Generic type parameter for return value: Screen[ScreenResultType]
    """
    def __init__(self, **kwargs):
        """
        Initialize the screen.
        
        Parameters:
        - name: str - Screen name
        - id: str - Unique identifier
        - classes: str - CSS classes
        """
    
    def compose(self) -> ComposeResult:
        """Compose the screen's widgets."""
    
    def dismiss(self, result=None) -> None:
        """
        Dismiss the screen with an optional result.
        
        Parameters:
        - result: Value to return when screen is dismissed
        """
    
    # Properties  
    title: str
    sub_title: str
    auto_focus: str | None

class ModalScreen(Screen):
    """A modal screen that doesn't cover the entire terminal."""
    pass

Event Handling Decorators

Decorators for handling events and creating background tasks in Textual applications.

def on(*selectors, **kwargs):
    """
    Decorator for handling events with CSS selector support.
    
    Parameters:
    - *selectors: CSS selectors to match against event targets
    - **kwargs: Additional event filtering options
    
    Usage:
    @on(Button.Pressed, "#my-button")
    def handle_button(self, event):
        pass
    """

def work(exclusive: bool = False, thread: bool = False):
    """
    Decorator for creating background tasks.
    
    Parameters:
    - exclusive: bool - Whether to cancel other workers when starting
    - thread: bool - Whether to run in a separate thread
    
    Usage:
    @work
    async def background_task(self):
        pass
    """

Utility Functions and Types

ComposeResult = Iterator[Widget]
"""Type alias for widget composition results."""

class AwaitMount:
    """Awaitable for widget mounting completion."""
    def __await__(self):
        """Wait for widget to be mounted."""

class MountError(Exception):
    """Raised when widget mounting fails."""

class ScreenStackError(Exception):
    """Raised when screen stack operations fail."""

Usage Examples

Basic Application Structure

from textual.app import App
from textual.widgets import Static
from textual.containers import Container

class MyApp(App):
    """A simple Textual application."""
    
    CSS_PATH = "app.css"  # Optional CSS file
    
    def compose(self):
        """Create the UI."""
        yield Container(
            Static("Hello World!"),
            id="main-container"
        )
    
    def on_mount(self):
        """Set up the application."""
        self.title = "My Application"
        self.sub_title = "v1.0.0"

# Run the application
if __name__ == "__main__":
    MyApp().run()

Screen Navigation

from textual.app import App
from textual.screen import Screen
from textual.widgets import Button

class SecondScreen(Screen):
    """A secondary screen."""
    
    def compose(self):
        yield Button("Go Back", id="back")
    
    def on_button_pressed(self, event):
        if event.button.id == "back":
            self.dismiss("result from second screen")

class MainApp(App):
    def compose(self):
        yield Button("Go to Second Screen", id="goto")
    
    def on_button_pressed(self, event):
        if event.button.id == "goto":
            self.push_screen(SecondScreen())

Event Handling with Decorators

from textual.app import App
from textual.widgets import Button, Input
from textual import on, work

class EventApp(App):
    def compose(self):
        yield Input(placeholder="Type something...", id="input")
        yield Button("Process", id="process")
    
    @on(Button.Pressed, "#process")
    def handle_process_button(self, event):
        """Handle the process button."""
        input_widget = self.query_one("#input", Input)
        self.process_text(input_widget.value)
    
    @work
    async def process_text(self, text: str):
        """Background task to process text."""
        # Simulate processing
        await asyncio.sleep(1)
        self.log(f"Processed: {text}")

Install with Tessl CLI

npx tessl i tessl/pypi-textual

docs

content.md

core-framework.md

events.md

index.md

styling.md

testing.md

widgets.md

tile.json