npyscreen

A Python ncurses-based application framework. Provides forms, widgets, and theme systems to support building complex TUI applications.

TUIncursesFormsWidgetsFramework

GitHub Overview

npcole/npyscreen

Automatically exported from code.google.com/p/npyscreen

Stars500
Watchers19
Forks112
Created:May 5, 2015
Language:Python
License:Other

Topics

None

Star History

npcole/npyscreen Star History
Data as of: 7/25/2025, 06:23 AM

npyscreen

npyscreen is a Python ncurses-based application framework. With its form-centric design philosophy, it enables efficient construction of complex TUI applications. It provides rich widgets and theme systems, excelling particularly in data entry and configuration screen creation.

Key Features

Form-Centric Design

  • Form-Based: Manage screens in form units
  • Widget Management: Widget placement within forms
  • Navigation: Inter-form transition system

Rich Widget Set

  • Input Widgets: Text, numeric, date input
  • Selection Widgets: Lists, checkboxes, radio buttons
  • Display Widgets: Labels, text areas, progress bars

Themes and Customization

  • Color Themes: Preset and custom themes
  • Widget Styles: Appearance customization
  • Layout Control: Flexible layout management

Installation

pip install npyscreen

Basic Usage

Simple Application

import npyscreen

class TestApp(npyscreen.NPSApp):
    def main(self):
        # Create form
        F = npyscreen.Form(name="Welcome to Npyscreen")
        
        # Add widgets
        t = F.add(npyscreen.TitleText, name="Text:")
        t.value = "Hello World!"
        
        # Display and edit form
        F.edit()

if __name__ == '__main__':
    App = TestApp()
    App.run()

Using Form Classes

import npyscreen

class MainForm(npyscreen.Form):
    def create(self):
        # Create widgets
        self.name_field = self.add(npyscreen.TitleText, 
                                  name="Name:", 
                                  value="John Doe")
        
        self.email_field = self.add(npyscreen.TitleText,
                                   name="Email:",
                                   value="[email protected]")
        
        self.age_field = self.add(npyscreen.TitleSlider,
                                 name="Age:",
                                 out_of=100,
                                 value=25)
        
        self.gender_field = self.add(npyscreen.TitleSelectOne,
                                    name="Gender:",
                                    values=["Male", "Female", "Other"],
                                    value=0)

class TestApp(npyscreen.NPSApp):
    def main(self):
        F = MainForm(name="User Information")
        F.edit()
        
        # Get input values
        print("Name:", F.name_field.value)
        print("Email:", F.email_field.value)
        print("Age:", F.age_field.value)
        print("Gender:", F.gender_field.get_selected_objects()[0])

if __name__ == '__main__':
    App = TestApp()
    App.run()

Advanced Features

Multiple Form Management

import npyscreen

class MenuForm(npyscreen.ActionForm):
    def create(self):
        self.add(npyscreen.TitleText, name="Welcome!", editable=False)
        self.menu_list = self.add(npyscreen.TitleSelectOne,
                                 name="Select Option:",
                                 values=["User Form", "Settings", "Exit"])
    
    def on_ok(self):
        selected = self.menu_list.get_selected_objects()[0]
        if selected == "User Form":
            self.parentApp.switchForm("USER")
        elif selected == "Settings":
            self.parentApp.switchForm("SETTINGS")
        elif selected == "Exit":
            self.parentApp.switchForm(None)

class UserForm(npyscreen.ActionForm):
    def create(self):
        self.name = self.add(npyscreen.TitleText, name="Name:")
        self.email = self.add(npyscreen.TitleText, name="Email:")
    
    def on_ok(self):
        # Save data processing
        npyscreen.notify_confirm(f"Saved: {self.name.value}")
        self.parentApp.switchForm("MAIN")
    
    def on_cancel(self):
        self.parentApp.switchForm("MAIN")

class SettingsForm(npyscreen.ActionForm):
    def create(self):
        self.theme = self.add(npyscreen.TitleSelectOne,
                             name="Theme:",
                             values=["Default", "Dark", "Light"])
        self.auto_save = self.add(npyscreen.RoundCheckBox,
                                 name="Auto Save")
    
    def on_ok(self):
        npyscreen.notify_confirm("Settings saved!")
        self.parentApp.switchForm("MAIN")
    
    def on_cancel(self):
        self.parentApp.switchForm("MAIN")

class MultiFormApp(npyscreen.NPSAppManaged):
    def onStart(self):
        self.addForm("MAIN", MenuForm, name="Main Menu")
        self.addForm("USER", UserForm, name="User Form")
        self.addForm("SETTINGS", SettingsForm, name="Settings")

if __name__ == '__main__':
    App = MultiFormApp()
    App.run()

Data List Display

import npyscreen

class ListForm(npyscreen.Form):
    def create(self):
        # Create data list
        self.data_list = self.add(npyscreen.MultiLineEdit,
                                 name="Data List:",
                                 values=[
                                     "Item 1: Description of item 1",
                                     "Item 2: Description of item 2",
                                     "Item 3: Description of item 3",
                                     "Item 4: Description of item 4",
                                 ])
        
        # List with filter functionality
        self.filtered_list = self.add(npyscreen.TitleMultiLine,
                                     name="Filtered List:",
                                     values=["Apple", "Banana", "Cherry", "Date"])
        
        # Search field
        self.search_field = self.add(npyscreen.TitleText,
                                    name="Search:",
                                    value="")
        
        # Real-time search instead of search button
        self.search_field.when_value_edited = self.filter_list
    
    def filter_list(self):
        search_term = self.search_field.value.lower()
        all_items = ["Apple", "Banana", "Cherry", "Date", "Elderberry", "Fig"]
        
        if search_term:
            filtered_items = [item for item in all_items 
                            if search_term in item.lower()]
        else:
            filtered_items = all_items
        
        self.filtered_list.values = filtered_items
        self.filtered_list.display()

class ListApp(npyscreen.NPSApp):
    def main(self):
        F = ListForm(name="List Example")
        F.edit()

if __name__ == '__main__':
    App = ListApp()
    App.run()

Custom Widgets

import npyscreen

class ProgressWidget(npyscreen.BoxTitle):
    _contained_widget = npyscreen.Slider
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.entry_widget.out_of = 100
        self.entry_widget.step = 1
    
    def set_progress(self, value):
        self.entry_widget.value = value
        self.display()
    
    def get_progress(self):
        return self.entry_widget.value

class CustomForm(npyscreen.Form):
    def create(self):
        self.progress = self.add(ProgressWidget,
                               name="Progress:",
                               value=50)
        
        self.increment_btn = self.add(npyscreen.MiniButtonPress,
                                    name="Increment")
        self.increment_btn.whenPressed = self.increment_progress
        
        self.decrement_btn = self.add(npyscreen.MiniButtonPress,
                                    name="Decrement")
        self.decrement_btn.whenPressed = self.decrement_progress
    
    def increment_progress(self):
        current = self.progress.get_progress()
        if current < 100:
            self.progress.set_progress(current + 10)
    
    def decrement_progress(self):
        current = self.progress.get_progress()
        if current > 0:
            self.progress.set_progress(current - 10)

class CustomApp(npyscreen.NPSApp):
    def main(self):
        F = CustomForm(name="Custom Widget Example")
        F.edit()

if __name__ == '__main__':
    App = CustomApp()
    App.run()

Themes and Styling

import npyscreen

# Custom theme definition
class CustomTheme(npyscreen.ThemeManager):
    default_colors = {
        'DEFAULT': 'WHITE_BLACK',
        'FORMDEFAULT': 'WHITE_BLACK',
        'NO_EDIT': 'BLUE_BLACK',
        'STANDOUT': 'CYAN_BLACK',
        'CURSOR': 'WHITE_BLACK',
        'CURSOR_INVERSE': 'BLACK_WHITE',
        'LABEL': 'GREEN_BLACK',
        'LABELBOLD': 'CYAN_BLACK',
        'CONTROL': 'YELLOW_BLACK',
        'IMPORTANT': 'GREEN_BLACK',
        'SAFE': 'GREEN_BLACK',
        'WARNING': 'YELLOW_BLACK',
        'DANGER': 'RED_BLACK',
        'CRITICAL': 'BLACK_RED',
        'GOOD': 'GREEN_BLACK',
        'GOODHL': 'GREEN_BLACK',
        'VERYGOOD': 'BLACK_GREEN',
        'CAUTION': 'YELLOW_BLACK',
        'CAUTIONHL': 'BLACK_YELLOW',
    }

class ThemedForm(npyscreen.Form):
    def create(self):
        # Themed widgets
        self.title = self.add(npyscreen.TitleText,
                             name="Title:",
                             color='IMPORTANT')
        
        self.description = self.add(npyscreen.TitleText,
                                   name="Description:",
                                   color='CONTROL')
        
        self.status = self.add(npyscreen.TitleSelectOne,
                              name="Status:",
                              values=["Active", "Inactive"],
                              color='GOOD')

class ThemedApp(npyscreen.NPSApp):
    def main(self):
        # Set custom theme
        npyscreen.setTheme(CustomTheme)
        
        F = ThemedForm(name="Themed Application")
        F.edit()

if __name__ == '__main__':
    App = ThemedApp()
    App.run()

Comparison with Other Libraries

FeaturenpyscreenTextualUrwidBlessed
Form ManagementExcellentMediumMediumLow
WidgetsRichRichRichLimited
Learning CurveMediumMediumHighLow
Data EntryOptimalGoodGoodBasic
CustomizationMediumHighHighLow

Use Cases

  • Data Entry Applications: Form-based data collection
  • Configuration Management Tools: System configuration screens
  • Database Management: Record editing and management
  • Surveys and Questionnaires: Interactive question systems

Community and Support

  • Stability: Long-term proven track record
  • Documentation: Detailed API documentation
  • Examples: Rich sample code
  • Compatibility: Python 2/3 support

npyscreen is a mature TUI framework that efficiently builds complex data entry applications through its form-centric design.