cursed package

Submodules

cursed.app module

Welcome to cursed!

This is a simplified wrapper around the curses library to provide an easy API to create a curses application, with easy concurrency across windows. It provides a simple menu implementation as well.

The best way to get started is to look at an example. Here’s the examples/menu.py example from the main repository, with extra comments to explain the various parts:

from cursed import CursedApp, CursedWindow, CursedMenu

# You instanciate the application through instanciating a CursedApp
app = CursedApp()

# The way to create windows is by creating classes derived from the
# CursedWindow class. These must have X, Y, WIDTH, and HEIGHT specified
# as class variables. 'max' or an integer value are valid for WIDTH and
# HEIGHT.
# A new gevent thread will be spawned for each window class.
# These act like singletons, and all functions should be class methods.
# The class itself will never be instanciated.
class MainWindow(CursedWindow):
    X, Y = (0, 0)
    WIDTH, HEIGHT = 'max', 23

    # To create a menubar, you create a CursedMenu instance in a MENU
    # class variable.
    # You add a menu to it with the add_menu function, and specify the
    # title, optional hotkey, and a list of menu items in the form of
    # (name, hotkey, callback) or (name, callback).
    # Menu items can be chosen by hotkeys or by the arrow keys and enter.
    MENU = CursedMenu()
    MENU.add_menu('File', key='f', items=[
        ('Save', 's', 'save'),
        ('Quit', 'q', 'quit'),
    ])
    MENU.add_menu('Edit', key='e', items=[
        ('Copy', 'c', 'copy'),
        ('Delete', 'delete')
    ])

    # Decorate your methods with @classmethod since no instance will ever
    # be instanciated.
    @classmethod
    def save(cls):
        # cls.addstr will write a string to x and y location (5, 5)
        cls.addstr('File->Save', 5, 5)

    @classmethod
    def quit(cls):
        # The quit function will run before the window exits.
        # Killing the window is triggered with cls.trigger('quit'),
        # which is the same way to trigger any other function in the
        # CursedWindow.
        cls.addstr('Quitting', 5, 5)

    @classmethod
    def copy(cls):
        cls.addstr('edit->copy', 5, 5)

    @classmethod
    def delete(cls):
        cls.addstr('edit->delete', 5, 5)

    @classmethod
    def update(cls):
        # The update function will be looped upon, so this is where you
        # want to put the main logic. This is what will check for key
        # presses, as well as trigger other functions through
        # cls.trigger.
        # Handle input here, other than what the menu will handle through
        # triggering callbacks itself.
        cls.addstr('x=10, y=12', 10, 12)
        # Press spacebar to open menu
        k = cls.getch()
        if k == 32:
            cls.openmenu()


class FooterWindow(CursedWindow):
    # This window will appear on the bottom, print the string
    # "Press f then q to exit", then quit. The message will stay on the
    # screen.
    # All windows must have called 'quit' to exit out of the program, or
    # simply ctrl-C could be pressed.
    X, Y = (0, 23)
    WIDTH, HEIGHT = 'max', 1

    @classmethod
    def init(cls):
        cls.addstr('Press f then q to exit')
        cls.refresh()
        cls.trigger('quit')


# You need to call app.run() to start the application, which handles
# setting up the windows.
result = app.run()
print(result)
# This checks if ctrl-C or similar was pressed to kill the application.
if result.interrupted():
    print('Ctrl-C pressed.')
else:
    # This will reraise exceptions that were raised in windows.
    result.unwrap()

That’s the essentials of it. Just remember to trigger(‘quit’) to all your windows if you want it to exit cleanly.

New in 2.0

Added pads!

Now, you can specify a pad CursedWindow like so:

class MyPad(CursedWindow):
    X, Y = 0, 0
    WIDTH, HEIGHT = 40, 40

    # set PAD to True
    PAD = True

    # the top left of the region to display
    PAD_X, PAD_Y = 0, 0

    # the virtual width and height, which you can scroll around to
    PAD_WIDTH, PAD_HEIGHT = 500, 500

    @classmethod
    def update(cls):
        ...
        # get new coordinates for top left of region
        ...
        cls.PAD_X, cls.PAD_Y = top_left_x, top_left_y
        ...
        # will now display the correct region in a smaller 40x40 display
        cls.refresh()

This is useful for when you might want to do something like scroll through a map. See examples/pad.py for an example which scrolls through text using the arrow keys.

class cursed.app.CursedApp

Bases: object

The CursedApp is the main class which is used to track windows that are created and finally run the application.

The CursedApp is initialized then run in the main function to build the windows.

Example:

from cursed import CursedApp, CursedWindow

app = CursedApp()

class MainWindow(CursedWindow):
    X, Y = (0, 0)
    WIDTH, HEIGHT = ('max', 'max')

    ...

result = app.run()
result.unwrap()
run()

Runs all the windows added to the application, and returns a Result object.

class cursed.app.Result

Bases: object

Result represents the object returned by app.run(), which may contain exception information.

err()

Returns the exception or None.

interrupted()

Returns True if the application was interrupted, like through Ctrl-C.

ok()

Return True if no exception occurred.

print_exc()

Prints the exception traceback.

unwrap()

Unwraps the Result, raising an exception if one exists.

cursed.window module

cursed.window

This contains the core logic used by cursed to create the window and offer the ncurses interface to display everything.

class cursed.window.CursedWindow

Bases: object

The CursedWindow should be the parent class of all Window classes you declare. Each should have class variables X, Y, WIDTH, and HEIGHT declared. WIDTH and HEIGHT can be integers or ‘max’.

Each function in a class derived from CursedWindow should be a classmethod, since no instances of the class will be created. The code will run as the single class, like a singleton.

classmethod addch(c, x=None, y=None, attr=None)

Add a character to a position on the screen or at cursor.

Parameters:
  • c – the character to insert
  • x – optional x value, or current x position
  • y – optional y value, or current y position
  • attr – optional attribute, like ‘bold’
classmethod addnstr(s, x=None, y=None, n=None, attr=None)

write at most n characters at specified position or cursor.

Parameters:
  • s – string to write
  • x – optional x value
  • y – optional y value
  • n – max number of characters
  • attr – optional attributes
classmethod addstr(s, x=None, y=None, attr=None)

write the string onto specified position or cursor, overwriting anything already at position.

Parameters:
  • s – string to write
  • x – optional x value
  • y – optional y value
  • attr – optional attributes
classmethod cx(*args)

Either the x position of cursor, or sets the x position. Example:

# gets the x position of cursor
my_x = cls.cx()

# set the x position to 20
cls.cx(20)

# moves right 2 spots
cls.cx(cls.cx() + 2)
Parameters:x – optional x position to move to
Returns:if x not specified, returns the x position of cursor
classmethod cy(*args)

Either the y position of cursor, or sets the y position. Example:

# gets the y position of cursor
my_y = cls.cy()

# set the y position to 20
cls.cy(20)

# moves down 2 spots
cls.cy(cls.cy() + 2)
Parameters:y – optional y position to move to
Returns:if y not specified, returns the y position of cursor
classmethod delch(x=None, y=None)

Delete a character at position, at cursor or specified position.

Parameters:
  • x – optional x value
  • y – optional y value
classmethod getch()

Get the integer value for the keypress, such as 27 for escape.

Returns:integer keycode of keypress
classmethod getkey()

Get the key that was pressed, or None. This is useful to simply check what key was pressed on the keyboard, ignoring special keys like the arrow keys.

Returns:character specifying key pressed, like ‘a’ or ‘C’
classmethod getstr(x=None, y=None, prompt=None)

Get string input from user at position, with optional prompt message.

Parameters:
  • x – optional x value
  • y – optional y value
  • prompt – message to prompt user with, example: “Name: “
Returns:

the string the user input

classmethod getwh()

Get the width and height of a window.

Returns:(width, height)
classmethod getxy()

Get the x and y position of the cursor.

Returns:(x, y)
classmethod hline(x=None, y=None, char='-', n=None)

Insert a horizontal line at position, at most n characters or width of window.

Parameters:
  • x – optional x value
  • y – optional y value
  • char – the character to print, default ‘-‘
  • n – the number of characters, default rest of width of window
classmethod inch(x=None, y=None)

Return the character and attributes of the character at the specified position in the window or cursor.

Parameters:
  • x – optional x value
  • y – optional y value
Returns:

(character, attributes)

classmethod insch(ch, x=None, y=None, attr=None)

Write a character at specified position or cursor, with attributes.

Parameters:
  • ch – character to insert
  • x – optional x value
  • y – optional y value
  • attr – optional attributes
classmethod insnstr(s, x=None, y=None, n=None, attr=None)

Insert a string at cursor or specified position, at most n characters. Cursor is not moved and characters to the right are shifted right. If n is zero, all characters are inserted.

Parameters:
  • s – the string
  • x – optional x value
  • y – optional y value
  • n – max characters to insert (0 is all)
  • attr – optional attributes
classmethod insstr(s, x=None, y=None, attr=None)

Insert a string at cursor or specified position. Cursor is not moved and characters to the right are shifted right.

Parameters:
  • s – the string
  • x – optional x value
  • y – optional y value
  • attr – optional attributes
classmethod instr(x=None, y=None, n=None)

Return a string at cursor or specified position. If n is specified, returns at most n characters.

Parameters:
  • x – optional x value
  • y – optional y value
  • n – optional max length of string
Returns:

string at position

classmethod move(x, y)

Moves cursor to x and y specified.

Parameters:
  • x – the x value, required
  • y – the y value, required
classmethod nextline()

Goes to the next line like a carriage return.

classmethod openmenu()

Opens the menu, if menu is specified for the window.

classmethod pad_move(x, y)

Reorients where the top left of the PAD should be, so it knows which region to display to the user.

Parameters:
  • x – the x element of the top left of the region to display
  • y – the y element of the top left of the region to display
classmethod redraw()

Redraws the window.

classmethod refresh()
classmethod sleep(seconds=0)

Tell the CursedWindow’s greenlet to sleep for seconds. This should be used to allow other CursedWindow’s greenlets to execute, especially if you have long running code in your update classmethod.

This is purely a restriction imposed by gevent, the concurrency library used for cursed. It is not truly parallel, so one long running greenlet can lock up execution of other windows. Calling cls.sleep() even with zero seconds (default) will allow other greenlets to start execution again.

There is no benefit to calling sleep with a number other than zero. Zero will allow other greenlets to take over just fine.

Parameters:seconds – seconds to sleep. default zero is fine.
classmethod trigger(func_name, *args, **kwargs)

Triggers a class function to be run by that window. This can be run across gevent coroutines to trigger other CursedWindow classes to run functions in their context.

This is also used to cause a window to “quit” by running something like:

MainWindow.trigger('quit')
Parameters:
  • func_name – the name of the function to run
  • args – the positional arguments, *args
  • kwargs – the keyword arguments, **kwargs
classmethod vline(x=None, y=None, char='|', n=None)

Insert a vertical line at position, at most n characters or height of window.

Parameters:
  • x – optional x value
  • y – optional y value
  • char – the character to print, default ‘|’
  • n – the number of characters, default rest of height of window
classmethod write(msg, x=None, y=None)

Writes a msg to the screen, with optional x and y values. If newlines are present, it goes to the next line.

Parameters:
  • msg – the message to print
  • x – optional x value
  • y – optional y value

cursed.exceptions module

cursed.exceptions

Base exceptions used by cursed.

exception cursed.exceptions.CursedCallbackError

Bases: exceptions.RuntimeError

Raised when a callback issue occurs, such as triggering a callback that doesn’t exist, example:

cls.trigger('typo_in_nmae')
exception cursed.exceptions.CursedMenuError

Bases: exceptions.RuntimeError

Raised when menus aren’t initialized correctly. Check in the CursedMenu documentation or the example projects for examples of proper creation of menus.

exception cursed.exceptions.CursedPadError

Bases: exceptions.ValueError

Raised when you screw up setting up a PAD type CursedWindow, either by not specifying the PAD_WIDTH or PAD_HEIGHT.

exception cursed.exceptions.CursedSizeError

Bases: exceptions.RuntimeError

Raised when a terminal size issue occurs, such as the menu not fitting in the width of the screen, or writing text outside of the window.

exception cursed.exceptions.CursedWindowError

Bases: exceptions.ValueError

Raised when you screw up with the initial CursedWindow class variables, like not setting WIDTH or HEIGHT.

cursed.meta module

cursed.meta

This contains the metaclass used to decorate all user classes that subclass CursedWindow, crucial for the curses interface to work.

class cursed.meta.CursedWindowClass

Bases: type

The CursedWindow has this as a metaclass, to keep track of all classes that inherit from it so that the app can instanciate the correct windows.

WINDOWS = []

cursed.menu module

cursed.menu

The menu data class. Most of the menu implementation is actually in the cursed.window module.

class cursed.menu.CursedMenu

Bases: object

The CursedMenu is the class which is used to initialize all the menus and items.

add_menu(title, key=None, items=None)

This creates a full menu with a title, an optional hotkey, and a list of items inside the menu, with their name, hotkey and callback.

Example:

MENU = CursedMenu('File', key='f', items=[
    ('Save', 's', 'save_callback'),
    ('Open', 'open_callback'),
    ('Quit', 'q', 'quit'),
])

Module contents

cursed

Simplified curses interface with concurrency, for quick and sane curses apps. Allows easy creation of windows and menus. Code for each window runs concurrently.

class cursed.CursedApp

Bases: object

The CursedApp is the main class which is used to track windows that are created and finally run the application.

The CursedApp is initialized then run in the main function to build the windows.

Example:

from cursed import CursedApp, CursedWindow

app = CursedApp()

class MainWindow(CursedWindow):
    X, Y = (0, 0)
    WIDTH, HEIGHT = ('max', 'max')

    ...

result = app.run()
result.unwrap()
run()

Runs all the windows added to the application, and returns a Result object.

class cursed.CursedWindow

Bases: object

The CursedWindow should be the parent class of all Window classes you declare. Each should have class variables X, Y, WIDTH, and HEIGHT declared. WIDTH and HEIGHT can be integers or ‘max’.

Each function in a class derived from CursedWindow should be a classmethod, since no instances of the class will be created. The code will run as the single class, like a singleton.

classmethod addch(c, x=None, y=None, attr=None)

Add a character to a position on the screen or at cursor.

Parameters:
  • c – the character to insert
  • x – optional x value, or current x position
  • y – optional y value, or current y position
  • attr – optional attribute, like ‘bold’
classmethod addnstr(s, x=None, y=None, n=None, attr=None)

write at most n characters at specified position or cursor.

Parameters:
  • s – string to write
  • x – optional x value
  • y – optional y value
  • n – max number of characters
  • attr – optional attributes
classmethod addstr(s, x=None, y=None, attr=None)

write the string onto specified position or cursor, overwriting anything already at position.

Parameters:
  • s – string to write
  • x – optional x value
  • y – optional y value
  • attr – optional attributes
classmethod cx(*args)

Either the x position of cursor, or sets the x position. Example:

# gets the x position of cursor
my_x = cls.cx()

# set the x position to 20
cls.cx(20)

# moves right 2 spots
cls.cx(cls.cx() + 2)
Parameters:x – optional x position to move to
Returns:if x not specified, returns the x position of cursor
classmethod cy(*args)

Either the y position of cursor, or sets the y position. Example:

# gets the y position of cursor
my_y = cls.cy()

# set the y position to 20
cls.cy(20)

# moves down 2 spots
cls.cy(cls.cy() + 2)
Parameters:y – optional y position to move to
Returns:if y not specified, returns the y position of cursor
classmethod delch(x=None, y=None)

Delete a character at position, at cursor or specified position.

Parameters:
  • x – optional x value
  • y – optional y value
classmethod getch()

Get the integer value for the keypress, such as 27 for escape.

Returns:integer keycode of keypress
classmethod getkey()

Get the key that was pressed, or None. This is useful to simply check what key was pressed on the keyboard, ignoring special keys like the arrow keys.

Returns:character specifying key pressed, like ‘a’ or ‘C’
classmethod getstr(x=None, y=None, prompt=None)

Get string input from user at position, with optional prompt message.

Parameters:
  • x – optional x value
  • y – optional y value
  • prompt – message to prompt user with, example: “Name: “
Returns:

the string the user input

classmethod getwh()

Get the width and height of a window.

Returns:(width, height)
classmethod getxy()

Get the x and y position of the cursor.

Returns:(x, y)
classmethod hline(x=None, y=None, char='-', n=None)

Insert a horizontal line at position, at most n characters or width of window.

Parameters:
  • x – optional x value
  • y – optional y value
  • char – the character to print, default ‘-‘
  • n – the number of characters, default rest of width of window
classmethod inch(x=None, y=None)

Return the character and attributes of the character at the specified position in the window or cursor.

Parameters:
  • x – optional x value
  • y – optional y value
Returns:

(character, attributes)

classmethod insch(ch, x=None, y=None, attr=None)

Write a character at specified position or cursor, with attributes.

Parameters:
  • ch – character to insert
  • x – optional x value
  • y – optional y value
  • attr – optional attributes
classmethod insnstr(s, x=None, y=None, n=None, attr=None)

Insert a string at cursor or specified position, at most n characters. Cursor is not moved and characters to the right are shifted right. If n is zero, all characters are inserted.

Parameters:
  • s – the string
  • x – optional x value
  • y – optional y value
  • n – max characters to insert (0 is all)
  • attr – optional attributes
classmethod insstr(s, x=None, y=None, attr=None)

Insert a string at cursor or specified position. Cursor is not moved and characters to the right are shifted right.

Parameters:
  • s – the string
  • x – optional x value
  • y – optional y value
  • attr – optional attributes
classmethod instr(x=None, y=None, n=None)

Return a string at cursor or specified position. If n is specified, returns at most n characters.

Parameters:
  • x – optional x value
  • y – optional y value
  • n – optional max length of string
Returns:

string at position

classmethod move(x, y)

Moves cursor to x and y specified.

Parameters:
  • x – the x value, required
  • y – the y value, required
classmethod nextline()

Goes to the next line like a carriage return.

classmethod openmenu()

Opens the menu, if menu is specified for the window.

classmethod pad_move(x, y)

Reorients where the top left of the PAD should be, so it knows which region to display to the user.

Parameters:
  • x – the x element of the top left of the region to display
  • y – the y element of the top left of the region to display
classmethod redraw()

Redraws the window.

classmethod refresh()
classmethod sleep(seconds=0)

Tell the CursedWindow’s greenlet to sleep for seconds. This should be used to allow other CursedWindow’s greenlets to execute, especially if you have long running code in your update classmethod.

This is purely a restriction imposed by gevent, the concurrency library used for cursed. It is not truly parallel, so one long running greenlet can lock up execution of other windows. Calling cls.sleep() even with zero seconds (default) will allow other greenlets to start execution again.

There is no benefit to calling sleep with a number other than zero. Zero will allow other greenlets to take over just fine.

Parameters:seconds – seconds to sleep. default zero is fine.
classmethod trigger(func_name, *args, **kwargs)

Triggers a class function to be run by that window. This can be run across gevent coroutines to trigger other CursedWindow classes to run functions in their context.

This is also used to cause a window to “quit” by running something like:

MainWindow.trigger('quit')
Parameters:
  • func_name – the name of the function to run
  • args – the positional arguments, *args
  • kwargs – the keyword arguments, **kwargs
classmethod vline(x=None, y=None, char='|', n=None)

Insert a vertical line at position, at most n characters or height of window.

Parameters:
  • x – optional x value
  • y – optional y value
  • char – the character to print, default ‘|’
  • n – the number of characters, default rest of height of window
classmethod write(msg, x=None, y=None)

Writes a msg to the screen, with optional x and y values. If newlines are present, it goes to the next line.

Parameters:
  • msg – the message to print
  • x – optional x value
  • y – optional y value
class cursed.CursedMenu

Bases: object

The CursedMenu is the class which is used to initialize all the menus and items.

add_menu(title, key=None, items=None)

This creates a full menu with a title, an optional hotkey, and a list of items inside the menu, with their name, hotkey and callback.

Example:

MENU = CursedMenu('File', key='f', items=[
    ('Save', 's', 'save_callback'),
    ('Open', 'open_callback'),
    ('Quit', 'q', 'quit'),
])

Table Of Contents

This Page