CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pytermgui

Python TUI framework with mouse support, modular widget system, customizable and rapid terminal markup language and more

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

file-loading.mddocs/

File Loading and Serialization

PyTermGUI provides comprehensive file loading and serialization capabilities for widget configuration management, including YAML and JSON support for creating widgets from configuration files and persisting widget states.

Capabilities

File Loaders

Base file loading system with support for different formats and widget namespace management.

class FileLoader:
    """Base file loader for widget configuration."""
    
    def __init__(self):
        """Initialize file loader."""
    
    def load(self, path: str) -> "WidgetNamespace":
        """
        Load widget configuration from file.
        
        Parameters:
        - path (str): Path to configuration file
        
        Returns:
        WidgetNamespace containing loaded widgets
        """
    
    def save(self, namespace: "WidgetNamespace", path: str):
        """
        Save widget namespace to file.
        
        Parameters:
        - namespace (WidgetNamespace): Widgets to save
        - path (str): Output file path
        """

class YamlLoader(FileLoader):
    """YAML file loader for widget configuration."""
    
    def load(self, path: str) -> "WidgetNamespace":
        """
        Load widgets from YAML file.
        
        Parameters:
        - path (str): Path to YAML file
        
        Returns:
        WidgetNamespace with loaded widgets
        
        Requires:
        PyYAML package (pip install PyYAML)
        """

class JsonLoader(FileLoader):
    """JSON file loader for widget configuration."""
    
    def load(self, path: str) -> "WidgetNamespace":
        """
        Load widgets from JSON file.
        
        Parameters:
        - path (str): Path to JSON file
        
        Returns:
        WidgetNamespace with loaded widgets
        """

Widget Namespace

Container for managing collections of loaded widgets with name-based access.

class WidgetNamespace:
    """Container for loaded widget configurations."""
    
    def __init__(self, widgets: dict[str, Widget] = None):
        """
        Create widget namespace.
        
        Parameters:
        - widgets (dict, optional): Named widget collection
        """
    
    def __getitem__(self, name: str) -> Widget:
        """Get widget by name."""
    
    def __setitem__(self, name: str, widget: Widget):
        """Set named widget."""
    
    def __contains__(self, name: str) -> bool:
        """Check if widget name exists."""
    
    @property
    def widgets(self) -> dict[str, Widget]:
        """Get all widgets as dictionary."""
    
    def add(self, name: str, widget: Widget):
        """Add named widget to namespace."""
    
    def remove(self, name: str) -> Widget:
        """Remove and return named widget."""
    
    def list_names(self) -> list[str]:
        """Get list of all widget names."""

Serialization System

Widget serialization for saving and loading widget states and configurations.

class Serializer:
    """Widget serialization and deserialization system."""
    
    def __init__(self):
        """Initialize serializer."""
    
    def dump(self, widget: Widget) -> dict:
        """
        Serialize widget to dictionary.
        
        Parameters:
        - widget (Widget): Widget to serialize
        
        Returns:
        Dictionary representation of widget
        """
    
    def load(self, data: dict) -> Widget:
        """
        Deserialize widget from dictionary.
        
        Parameters:
        - data (dict): Serialized widget data
        
        Returns:
        Reconstructed widget instance
        """
    
    def dump_to_file(self, widget: Widget, filename: str):
        """Save widget to file."""
    
    def load_from_file(self, filename: str) -> Widget:
        """Load widget from file."""

# Global serializer instance
serializer: Serializer

Configuration File Formats

YAML Configuration

Example YAML widget configuration format:

# widgets.yaml
main_window:
  type: Window
  title: "My Application"
  width: 60
  height: 20
  widgets:
    - type: Label
      value: "[bold]Welcome to PyTermGUI"
    - type: Container
      widgets:
        - type: Button
          label: "Click Me"
          onclick: "handle_click"
        - type: InputField
          prompt: "Enter text:"
          value: ""

settings_dialog:
  type: Window  
  title: "Settings"
  width: 40
  height: 15
  widgets:
    - type: Checkbox
      label: "Enable sound"
      checked: true
    - type: Slider
      min_value: 0
      max_value: 100
      value: 50

JSON Configuration

Example JSON widget configuration format:

{
  "main_form": {
    "type": "Container",
    "width": 50,
    "widgets": [
      {
        "type": "Label",
        "value": "[210 bold]User Registration"
      },
      {
        "type": "InputField", 
        "prompt": "Username:",
        "id": "username_field"
      },
      {
        "type": "InputField",
        "prompt": "Password:",
        "id": "password_field"
      },
      {
        "type": "Button",
        "label": "Register",
        "onclick": "handle_register"
      }
    ]
  }
}

Usage Examples

Loading Widgets from YAML

import pytermgui as ptg

# Load widgets from YAML file
loader = ptg.YamlLoader()
namespace = loader.load("widgets.yaml")

# Access loaded widgets by name
main_window = namespace["main_window"]
settings_dialog = namespace["settings_dialog"]

# Use in window manager
with ptg.WindowManager() as manager:
    manager.add(main_window)

Loading Widgets from JSON

import pytermgui as ptg

# Load from JSON configuration
loader = ptg.JsonLoader()
namespace = loader.load("forms.json")

# Get specific widget
form = namespace["main_form"]

# Add to application
with ptg.WindowManager() as manager:
    window = ptg.Window(form, title="Registration")
    manager.add(window)

Widget Serialization

import pytermgui as ptg

# Create widget hierarchy
container = ptg.Container(
    "[bold]Settings Panel",
    "",
    ptg.Checkbox(checked=True, label="Enable notifications"),
    ptg.Slider(value=75, min_value=0, max_value=100),
    ptg.Button("Save", lambda btn: print("Saved")),
    width=40
)

# Serialize widget to dictionary
widget_data = ptg.serializer.dump(container)
print(widget_data)

# Save to file
ptg.serializer.dump_to_file(container, "settings.json")

# Later, load widget back
restored_container = ptg.serializer.load_from_file("settings.json")

Dynamic Widget Creation

import pytermgui as ptg

def create_form_from_config(config_file):
    """Create form widgets from configuration."""
    loader = ptg.JsonLoader()
    namespace = loader.load(config_file)
    
    forms = {}
    for name, widget in namespace.widgets.items():
        if isinstance(widget, ptg.Container):
            forms[name] = widget
    
    return forms

# Load multiple forms
forms = create_form_from_config("forms.json")

# Create tabbed interface
current_form = "login"

def switch_form(form_name):
    global current_form
    current_form = form_name
    # Update display logic here

# Use forms in application
with ptg.WindowManager() as manager:
    window = ptg.Window(
        forms[current_form],
        title="Forms Demo"
    )
    manager.add(window)

Configuration with Callbacks

import pytermgui as ptg

# Define callback functions
def handle_submit(button):
    print("Form submitted!")

def handle_cancel(button):
    print("Form cancelled!")

# Callback registry for configuration files
CALLBACKS = {
    "handle_submit": handle_submit,
    "handle_cancel": handle_cancel
}

def load_with_callbacks(config_file):
    """Load widgets and bind callbacks."""
    loader = ptg.JsonLoader()
    namespace = loader.load(config_file)
    
    # Process widgets to bind callbacks
    for widget in namespace.widgets.values():
        bind_callbacks_recursive(widget)
    
    return namespace

def bind_callbacks_recursive(widget):
    """Recursively bind callbacks to widgets."""
    if hasattr(widget, 'onclick') and isinstance(widget.onclick, str):
        # Replace string callback name with actual function
        callback_name = widget.onclick
        if callback_name in CALLBACKS:
            widget.onclick = CALLBACKS[callback_name]
    
    # Process child widgets
    if hasattr(widget, 'widgets'):
        for child in widget.widgets:
            bind_callbacks_recursive(child)

# Usage
namespace = load_with_callbacks("interface.json")

Saving Widget State

import pytermgui as ptg

class StatefulForm:
    """Form that can save and restore its state."""
    
    def __init__(self):
        self.form = ptg.Container(
            "[bold]Stateful Form",
            "",
            ptg.InputField(prompt="Name:", id="name"),
            ptg.InputField(prompt="Email:", id="email"),
            ptg.Checkbox(id="newsletter", label="Newsletter"),
            "",
            ptg.Button("Save State", self.save_state),
            ptg.Button("Load State", self.load_state),
            width=50
        )
    
    def save_state(self, button):
        """Save current form state."""
        ptg.serializer.dump_to_file(self.form, "form_state.json")
        print("State saved!")
    
    def load_state(self, button):
        """Restore form state."""
        try:
            restored_form = ptg.serializer.load_from_file("form_state.json")
            # Update current form with restored values
            self.update_form_values(restored_form)
            print("State loaded!")
        except FileNotFoundError:
            print("No saved state found")
    
    def update_form_values(self, restored_form):
        """Update form with restored values."""
        # Implementation depends on specific widget ID matching
        for widget in restored_form.widgets:
            if hasattr(widget, 'id') and widget.id:
                current_widget = self.find_widget_by_id(widget.id)
                if current_widget:
                    # Copy values from restored widget
                    if hasattr(widget, 'value'):
                        current_widget.value = widget.value
                    if hasattr(widget, 'checked'):
                        current_widget.checked = widget.checked

# Usage
form = StatefulForm()

Install with Tessl CLI

npx tessl i tessl/pypi-pytermgui

docs

animations.md

colors-markup.md

file-loading.md

index.md

terminal.md

utilities.md

widgets.md

window-management.md

tile.json