0

I'm showing some live stats from a process with curses. I'm newby with this library, so I followed this example to implement what i need.

I write this small version which summarizes my problem:

import time
import curses

def draw_menu(stdscr):
    global data
    # Turn cursor off
    curses.curs_set(False)

    # Rendering text
    stdscr.addstr(2, 5, "Help me please")
    stdscr.addstr(5, 5, data)
    # Refresh the screen
    stdscr.refresh()
    time.sleep(3)

data = 'some initial value'
for i in xrange(2):
    curses.wrapper(draw_menu)
    # Do some stuff to update values shown in the menu
    data = 'updated value {}'.format(i)
    time.sleep(3)

After initial call to draw_menu, I need to update values displayed on menu. While update is running (in this example I used time.sleep), values are removed from window and it goes back to 'normal terminal mode', I don't know why.

I would like to update data while staying all time with this 'help me please' message & data displayed.

I think that I could solve this using threads but, since complete code is far more complicated, I would like to avoid threads.

How can I solve this?

Rodrigo Laguna
  • 1,796
  • 1
  • 26
  • 46

1 Answers1

0

Your example should put the loop inside the call to curses.wrapper, e.g., something like

import curses

def draw_menu(stdscr):
    global data
    # Turn cursor off
    curses.curs_set(False)

    # Rendering text
    stdscr.addstr(2, 5, "Help me please")
    stdscr.addstr(5, 5, data)
    # Refresh the screen
    stdscr.refresh()
    curses.napms(3000)

def draw_menu_loop(w):
    global data
    data = 'some initial value'
    for i in xrange(2):
        draw_menu(w)
        # Do some stuff to update values shown in the menu
        data = 'updated value {}'.format(i)
    curses.napms(3000)

curses.wrapper(draw_menu_loop)

By the way (actually should be a new question), your example used time.sleep, which interferes with timely updates to the screen. Use curses.napms, which does not have that drawback.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • So I must do a kind of wrapper of all my code (lets call it main()) and then execute curses.wrapper(main)? there is no way to freeze the screen preventing it from going back to 'normal terminal mode'? – Rodrigo Laguna Jun 26 '17 at 13:20
  • Its not working. draw_menu_loop without () throws SyntaxError and adding () results in "draw_menu_loop() takes no arguments (1 given)". I also tried writng "draw_menu_loop(foo)" and it run but only shows screen without any text – Rodrigo Laguna Jun 27 '17 at 23:28