Search code examples
pythonncursescurses

Python curses dilemma


I'm playing around a little with Python and curses.

When I run

import time
import curses

def main():
    curses.initscr()
    curses.cbreak()
    for i in range(3):
        time.sleep(1)
        curses.flash()
        pass
    print( "Hello World" )
    curses.endwin()

if __name__ == '__main__':
    main()

if I wait all the way through, curses.endwin() gets called so everything works out fine. However, if I cut it short with Ctrl-C, curses.endwin() never gets called so it screws up my terminal session.

What is the proper way to handle this situation? How can I make sure that no matter how I try to end/interrupt the program (e.g. Ctrl-C, Ctrl-Z), it doesn't mess up the terminal?


Solution

  • You could do this:

    def main():
        curses.initscr()
    
        try:
            curses.cbreak()
            for i in range(3):
                time.sleep(1)
                curses.flash()
                pass
            print( "Hello World" )
        finally:
            curses.endwin()
    

    Or more nicely, make a context wrapper:

    class CursesWindow(object):
        def __enter__(self):
            curses.initscr()
    
        def __exit__(self):
            curses.endwin()
    
    def main():
        with CursesWindow():
            curses.cbreak()
            for i in range(3):
                time.sleep(1)
                curses.flash()
                pass
            print( "Hello World" )