Python ncurses: no muestra la pantalla hasta la primera pulsación de tecla, aunque la actualización es la primera

El siguiente código le permite caminar alrededor de una pequeña cuadrícula en la pantalla con las teclas de flecha que ponen “.” donde has explorado o estado al lado. A pesar de que tengo mi actualización antes del primer getch (para obtener una pulsación de tecla), la pantalla no muestra nada hasta que se haya movido de su posición inicial. ¿No debería el addstr seguido de actualizar inmediatamente y luego el getch espera después de eso? Incluso intenté agregar un stdscr.refresh (), pero eso tampoco ayudó. ¿Cómo hago para que la pantalla se actualice inmediatamente antes de esperar el primer golpe de tecla?

import curses def start(stdscr): curses.curs_set(0) movement = curses.newpad(10, 10) cur_x, cur_y = 5, 5 while True: movement.addstr(cur_y, cur_x, '@') for (x_off, y_off) in [(-1,0),(1,0),(0,-1),(0,1)]: movement.addstr(cur_y + y_off, cur_x + x_off, '.') movement.refresh(1, 1, 0, 0, 7, 7) #Nothing is displayed until after the first key-stroke key_stroke = stdscr.getch() move_attempt = False if 0 < key_stroke  1: cur_y -= 1 elif key_stroke == curses.KEY_DOWN and cur_y  1: cur_x -= 1 elif key_stroke == curses.KEY_RIGHT and cur_x < 8: cur_x += 1 else: pass if __name__ == '__main__': curses.wrapper(start) 

Los documentos están rotos. Usé maldiciones en el pasado, pero libncurses es nuevo para mí.

Mi primer indicio vino de ncurses (3) :

La biblioteca ncurses permite la manipulación de estructuras de datos, llamadas ventanas, que se pueden considerar como matrices bidimensionales de caracteres que representan todo o parte de una pantalla CRT. Se proporciona una ventana predeterminada llamada stdscr, que es el tamaño de la pantalla del terminal. Otros pueden ser creados con newwin. … Las ventanas especiales llamadas almohadillas también pueden ser manipuladas. Estas son ventanas que no están limitadas al tamaño de la pantalla y cuyo contenido no necesita ser mostrado completamente.

Pero luego la actualización (3) se puso decididamente evasiva:

La rutina wrefresh funciona llamando primero a wnoutrefresh, que copia la ventana nombrada a la pantalla virtual, y luego llama a doupdate, que compara la pantalla virtual con la pantalla física y realiza la actualización real. … La frase “copia la ventana nombrada en la pantalla virtual” es ambigua. Lo que realmente sucede es que todas las líneas tocadas (modificadas) en la ventana se copian en la pantalla virtual. Esto afecta a los progtwigs que usan ventanas superpuestas; significa que si se superponen dos ventanas, puede actualizarlas en cualquier orden y la región de superposición se modificará solo cuando se cambie explícitamente. [énfasis mío]

lo que me impulsó a intentar agregar

 stdscr.refresh() 

después de su pad.refresh() que funcionó. Y luego lo moví más hacia arriba en start() para ver si realmente era necesario en cada modificación de pad. Me moví todo el camino hasta el primer punto, hay un stdscr para trabajar con rendimiento:

 def start(stdscr): stdscr.refresh() curses.curs_set(0) … 

que huele a progtwigción vudú, pero no voy a mirar las entrañas de una biblioteca de 20 años hecha para hacer frente a los ttys de vidrio para tratar de asimilarlos.

Agregue stdscr.refresh() algún momento antes de movement.refresh() para resolver el problema.

Al agregar time.sleep(1) después de la instrucción de actualización, se escribe en la pantalla, pero luego desaparece cuando se llama a stdscr.getch() , pero solo la primera vez. Probablemente tiene que ver con algún tipo de inicialización retrasada de stdscr.

Llamar a stdscr.refresh() después de movement.refresh() tiene el mismo efecto: la primera vez que stdscr.refresh() por el bucle stdscr.refresh() borra la pantalla, pero no en los tiempos subsiguientes a través del bucle. Al llamar a stdscr.refresh() principio del progtwig, se obtiene esta extraña primera vez que se actualiza.

Cuando use un pad, por alguna razón, no sé por qué, debe llamar a curses.doupdate después de invocar la refresh del pad.