¿Qué es curses?

Curses es un módulo de Python que nos sirve para poder crear interfaces gráficas y control de teclado en aplicaciones de consola.

Técnicamente curses es una módulo de Python que hace de wrapper de las librerías de curses de C, pero como quiero que esto sean unos apuntes prácticos sobre su uso y no quiero extenderme voy a dejar toda la teoría de un lado.

¿Por qué curses?

El hecho de que creemos aplicaciones de consola no significa que tengan que ser scripts con los que sólo podamos interactuar con ellos a través de parámetros y ficheros de entrada, podemos hacer aplicaciones "bonitas" a la vista, con un interfaz "elegante" y que se puedan usar de forma interactiva. (El uso del entrecomillado es porque dependerá del creador que sean bonitas y/o elegantes, en mi caso lo veo bastante difícil)

Hace unos meses comencé a experimentar y crear algunas pruebas pero me limité a copiar ejemplos y adaptarlos. Meses después no entiendo el código, por lo cual puedo considerar que esas pruebas no valieron para nada, solo para perder el tiempo. La idea que tengo ahora es comenzar con la documentación oficial, así que esto serán unos apuntes, espero que breves, de como usar curses.

Inicializando la aplicación

Esto es un ejemplo de inicializado completo de una aplicación, después comentaré línea a línea en que consiste.

import curses

def main(stdscr):
    stdscr = curses.initscr()
    curses.noecho()
    curses.cbreak()
    stdscr.keypad(True)

curses.wrapper(main)

El ejemplo anterior lo que hace es usar un método main donde se ejecutará todo el código, en este caso lo único que hay es la inicialización de curses.

import curses Es el paquete que debemos importar, el módulo como tal

stdscr = curses.initscr() Es la orden que realmente inicializa curses

curses.noecho() Elimina el echo del input. Para no tener el cursor del terminal pintando nada y que lo que tecleemos no se escriba.

curses.cbreak() Es el modo cbreak por el cual no hace falta que pulsemos intro para que la aplicación sea consciente de las pulsaciones de las teclas. Para que la aplicación pueda reaccionar directamente a la pulsación de las teclas.

stdscr.keypad(True) Para poder usar y procesar las pulsaciones del keypad, con esta opción curses nos facilita poder usar valores especiales como curses.KEY_LEFT

Curses Wrapper

Sobre el wrapper quiero hablar un poco mas porque no lo conocía y me hubiese resultado muy útil. Si veis en el ejemplo anterior hemos modificado comportamientos de la consola, como por ejemplo que no muestre el área de echo, pues bien, si ejecutamos una aplicación curses y falla es posible que regresemos a la terminal mal configurada.

A la hora de depurar es muy común acabar en la terminal sin echo y es un incordio trabajar, a veces incluso prefería abrir una terminal nueva para trabajar, pues parece ser que el wrapper se encarga de dejarlo todo como estaba cuando se termine la aplicación.

Importante fijarse que en la declaración de la función main le decimos que espera un parámetro stdsrc

Terminando la aplicación

Como ya he contado, al crear la aplicación es posible que cambiemos comportamientos del terminal, así que a la hora de terminar la aplicación deberemos dejarlo como estaba.

Esta sería la opción para el caso anterior:

curses.nocbreak()
stdscr.keypad(False)
curses.echo()

También tenemos la función curses.endwin() que dejará la terminal en el estado anterior a nuestra ejecución.

Terminando

Hasta aquí el cómo crear una aplicación, nada de ventanas aún ni de como pintar nada, eso iré publicándolo mas adelante, según vaya probando e investigando.

Disclaimer

Estoy escribiendo estos posts según aprendo, cuando acabo de aprender algo lo documento, por lo cual seguramente haya errores y muchas cosas que iré aprendiendo y espero que actualizando. Podría hacerlos mucho mas extensos, pero me resulta mas útil que cada post trate sobre un tema en concreto.

Cualquier comentario es bienvenido.