noibe
noibe

Reputation: 347

Continuously update string in python curses

Trying to learn curses, I wrote this script that lets the user input two numbers, then outputs their sum and their difference:

import curses

screen = curses.initscr()
screen.refresh()

height = 4
width = 25
abwindow =  curses.newwin(height, width, int(0.15*int(curses.LINES)), int(curses.COLS/2) - width)
abwindow.addstr(1, 2, "a is : ")
abwindow.addstr(2, 2, "b is : ")

abwindow.border()
abwindow.refresh()

sumdiffwindow = curses.newwin(height, width, int(0.15*int(curses.LINES)), int(curses.COLS/2))
sumdiffwindow.addstr(1, 2, "a + b is : ")
sumdiffwindow.addstr(2, 2, "a - b is : ")

sumdiffwindow.border()
sumdiffwindow.refresh()

atocheck = abwindow.getstr(1, 10, 7)
btocheck = abwindow.getstr(2, 10, 7)

try:
    a = float(atocheck)
    b = float(btocheck)
    sum = a + b
    diff = a - b
    sumdiffwindow.addstr(1, 14, "%g" %(sum))
    sumdiffwindow.addstr(2, 14, "%g" %(diff))
except ValueError:
    sumdiffwindow.addstr(1, 14, "nan")
    sumdiffwindow.addstr(2, 14, "nan")

sumdiffwindow.refresh()
curses.curs_set(0)

while True:
    curses.noecho()
    c = screen.getch(1, 1)
    if c == ord('q') or c == ord('Q'):
        break

curses.endwin()

Once the two numbers are inputed, (if they are numbers) it calculates the sum and difference, and then it idles until the user presses 'q' to go back to the terminal. How can I change it so that I can update a and b as much as I want (using the keyboard up and down arrows to navigate between the two input boxes), while continuously displaying their current sum and difference?

Upvotes: 2

Views: 1764

Answers (2)

mee
mee

Reputation: 708

I'm also new to curses but I tried a little to help you. After showing the result, if you press any key except q, all will be renewed like the biginning. But if you press q, the code will exit.

import curses
import time
import sys

def main():
    screen = curses.initscr()
    screen.refresh()
    height = 4
    width = 25
    abwindow =  curses.newwin(height, width, int(0.15*int(curses.LINES)), int(curses.COLS/2) - width)
    abwindow.addstr(1, 2, "a is : ")
    abwindow.addstr(2, 2, "b is : ")

    abwindow.border()
    abwindow.refresh()

    sumdiffwindow = curses.newwin(height, width, int(0.15*int(curses.LINES)), int(curses.COLS/2))
    sumdiffwindow.addstr(1, 2, "a + b is : ")
    sumdiffwindow.addstr(2, 2, "a - b is : ")

    sumdiffwindow.border()
    sumdiffwindow.refresh()
    curses.echo()
    atocheck = abwindow.getstr(1, 10, 7)
    btocheck = abwindow.getstr(2, 10, 7)

    try:
        a = float(atocheck)
        b = float(btocheck)
        sum = a + b
        diff = a - b
        sumdiffwindow.addstr(1, 14, "%g" %(sum))
        sumdiffwindow.addstr(2, 14, "%g" %(diff))
    except ValueError:
        sumdiffwindow.addstr(1, 14, "nan")
        sumdiffwindow.addstr(2, 14, "nan")
    sumdiffwindow.refresh()
    curses.curs_set(0)
    curses.noecho()
    c = screen.getch(1, 1)
    if c == ord('q') or c == ord('Q'):
        sys.exit()


while True:
    main()

Upvotes: 2

Thomas Dickey
Thomas Dickey

Reputation: 54475

You can do this by setting the window timeout to a small value, e.g., 10 (milliseconds). If you use nodelay, it will not work with the arrow-keys.

Doing that makes getch return (perhaps with an error...) after a short period of time. Once it has done that, update other parts of the screen, and go back, asking getch for input until it returns something valid (such as an up-arrow key).

Upvotes: 2

Related Questions