Continuando con el tema de curses, en el post anterior apunté como crear una aplicación con curses, hoy quiero compartir mis notas sobre windows y pads. No soy muy de mezclar términos en español con palabras en inglés, pero al tratarse de textos técnicos, no me queda mas remedio para que a la hora de continuar documentándonos nos sea mas sencillo.

¿Qué es un Window?

Los windows son las abstracciones más básicas en curses y representan rectángulos en la pantalla. Por ejemplo, cuando inicializamos curses creando el strsrc estamos creando un window, una ventana, que ocupa la pantalla al completo.

Dentro de las ventanas se pueden crear mas ventanas. Aún pudiendo crear aplicaciones con una sola ventana lo mas común es ir añadiendo mas ventanas, esto se realiza a través de la función newwin() .

begin_x = 20;
begin_y = 7
height = 5;
width = 40
win = curses.newwin(height, width, begin_y, begin_x)

OJO: En curses las coordenadas se pasan en el siguiente orden "y,x", lo mas común en librerías y herramientas de este tipo es pasar primero la coordenada x, pero no es el caso de curses.

Podemos sacar el número de lineas y de columnas con las siguientes sentencias:

curses.LINES
curses.COLS

¿Qué es un Pad?

Un pad es una ventana que puede contener mas contenido del que muestra, esto es que puede ocupar toda la pantalla entera pero podemos mostrar solo una parte que nos interese.

Esto me ha costado bastante comprenderlo y he tenido que hacer algunas pruebas para acabar comprendiendo mas o menos como funciona. Copio el ejemplo de la documentación y lo explico:

pad = curses.newpad(100, 100)
for y in range(0, 99):
 for x in range(0, 99):
     pad.addch(y,x, ord('a') + (x*x+y*y) % 26)
pad.refresh( 0,0, 5,5, 20,75)

El ejemplo anterior lo que hace es crear un pad de 100x100 y cargarlo de letras, el truco viene a la hora de pintarlo, eso lo hace con el refresh()

Por parejas de parámetros:

  • (0,0) Son las coordenadas desde donde queremos que empiece a leer los datos del pad, por ejemplo: imaginemos que tengo un pad de la siguiente manera
       abcde
       fghij
       klmno
       pqers
    con (0,0) le diría que quiero que empiece a leer en la letra a, pero por ejemplo podría cambiar las coordenadas para decirle que quiero empezar a leer en la g.
  • (5,5) Las coordenadas superiores de la pantalla desde donde queremos empezar a mostrar el pad. En este caso se desplaza 5 lineas y 5 columnas y ahí empieza
  • (20,75) Las coordenadas inferiores hasta las que queremos pintar.

Modificando el ejemplo:

Si en el ejemplo de las letras del abecedario, hiciesemos un refresh del tipo pad.refresh(1,1,2,2,20,75) lo que le diriamos es que se fuese a la posición 2,2 de la pantalla y mostrase:

ghij
lmno
qers

La verdad es que aún me queda mucho que experimentar con pads, a parte de que no les encuentro utilidad aún, que seguro que cuando empiece a usarlos no podré vivir sin ellos y serán imprescindibles.

Refrescar contenido de las ventanas

Para refrescar el contenido de las ventanas tendremos que hacerlo a mano, para ello contamos con las funciones

  • refresh() Que actualiza una ventana y ejecuta el cambio en la pantalla
  • noutrefresh() Actualiza los datos de como se debe representar la ventana. NoOUTputREFRESH
  • doupdate() Actualiza la pantalla con los datos de las ventanas.

Explicando un poco como funcionan las dos últimas. Imaginando que tenemos dos ventanas, podemos hacer lo siguiente:

window1.noutrefresh()
window2.noutrefresh()
curses.doupdate()

Esto lo que haría sería modificar internamente la ventana 1 y la 2, pero hasta que no ejecutamos el doupdate no veríamos las modificaciones en la ventana. Creo que teniendo varias ventanas esta sería la forma correcta de hacerlo.