Question

I'm building a python curses application.

I have two ways of printing to the curses window: print x, and windows.addstr(x) (and the other similar window.* options).

However, for debugging purposes, I'd like to be able to print to the standard console, so when I exit the curses window, I have the infomation waiting for me to be seen. I would normally just use print x, but that prints to the curses window.

sys.stout.write() also fails.

How can I do this?

After using sys.stdout after os.fdopen, this is the traceback

 curses.nocbreak()
 _curses.error: nocbreak() returned ERR
 close failed in file object destructor:
 sys.excepthook is missing
 lost sys.stderr
Was it helpful?

Solution

To do as you say, here is a snippet I used:

class StdOutWrapper:
    text = ""
    def write(self,txt):
        self.text += txt
        self.text = '\n'.join(self.text.split('\n')[-30:])
    def get_text(self,beg,end):
        return '\n'.join(self.text.split('\n')[beg:end])

if __name__ == "__main__":
    mystdout = StdOutWrapper()
    sys.stdout = mystdout
    sys.stderr = mystdout

    screen = curses.initscr()
    curses.noecho()
    curses.cbreak()

    # do your stuff here
    # you can also output mystdout.get_text() in a ncurses widget in runtime

    screen.keypad(0)
    curses.nocbreak()
    curses.echo()
    curses.endwin()
    sys.stdout = sys.__stdout__
    sys.stderr = sys.__stderr__
    sys.stdout.write(mystdout.get_text())

The neat thing with that trick, is that you can also output your stdout during ncurse runtime in a widget. Of course the internal representation of StdOutWrapper can be tweaked as you want, to better match your needs.

OTHER TIPS

Why don't you use the standard logging module?

Combine it with curses.wrapper, and you are good to go


EDIT:

You can see example here: https://stackoverflow.com/a/28102809/26494

If you just want to log to file:

import logging
import curses

def draw(stdscr):
    logger = logging.getLogger(__file__)
    hdlr = logging.FileHandler(__file__ + ".log")
    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
    hdlr.setFormatter(formatter)
    logger.addHandler(hdlr)
    logger.setLevel(logging.DEBUG)

    logger.info("begin")

    curses.init_pair(1, curses.COLOR_CYAN, curses.COLOR_BLACK)
    stdscr.addstr(0, 0, 'hello', curses.color_pair(1))
    logger.info("yeah")
    stdscr.getch()
    logger.info("end")


if __name__ == '__main__':
    curses.wrapper(draw)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top