1

I'm trying to make a python script that takes input from stdin, displays GUI in terminal using curses and then when user finishes interaction outputs the result to the stdout. Good example of this behaviour is selecta but it's written in ruby.

I can't make curses display anything. This is minimal (it only displays one character and waits for one character) example of what I tried so far:

import os, sys
import curses

c = None

old_out = sys.__stdout__
old_in = sys.__stdin__
old_err = sys.__stderr__
sys.__stdout__ = sys.stdout = open('/dev/tty', 'w')
sys.__stdin__ = sys.stdin = open('/dev/tty')
sys.__stderr__ = sys.stderr = open('/dev/tty')


def show_a(s):
    global c
    s.addch(ord('a'))
    c = s.getch()

curses.wrapper(show_a)

sys.stdin.flush()
sys.stdout.flush()
sys.stderr.flush()
sys.stdin.close()
sys.stdout.close()
sys.stderr.close()
sys.__stdout__ = sys.stdout = old_out
sys.__stdin__ = sys.stdin = old_in
sys.__stderr__ = sys.stderr = old_err

print(c)

When I try to use echo $(python3 show_a.py) nothing is displayed but after pressing any key its number is displayed:

curses displays nothing in terminal

Is something like this even possible using curses, if so how to do this?

1 Answer 1

2

It doesn't work because the print statement is writing to the same standard output as curses.wrapper. You can either defer that print until after you have restored sys.stdout, or you could use the file= property something like this:

printf(s.getch(), file=old_out)

For the other (ordering) problem, it sounds as if you need to amend the code to do a refresh after the getch (to make curses display it), and depending on what version of curses, a flush of the standard output would then be helpful.

Further reading:

Sign up to request clarification or add additional context in comments.

1 Comment

Oh, yes, that's a mistake that I made when I was simplifying the example, but I'm afraid it's irrelevant or at least there's a bigger problem: curses output (s.addch(ord('a'))) is not displayed and this should happen before result of s.getch() is printed. Nevertheless I fixed the code, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.