以下部分内容引用来自网络
http://www.codesec.net/view/180213.html
http://www.cnblogs.com/starof/p/4703820.html
一:介绍 curses
curses 库 ( ncurses ) 提供了控制字符屏幕的独立于终端的方法。curses 是大多数类似于 UNIX 的系统(包括 Linux)的标准部分,而且它已经移植到 Windows 和其它系统,很遗憾的是我在Windows下并不能使用T__T,所以只能在Ubuntu上继续折腾;
二、语法入门
1、打开和关闭一个curses 应用程序
在任何代码执行前都先要初始化curses。初始化操作就是调用initscr()函数,该函数根据不同设备返回一个window对象代表整个屏幕
import curses
stdscr = curses.initscr()
使用curses通常要关闭屏幕回显,目的是读取字符仅在适当的环境下输出。这就需要调用noecho()方法
curses.noecho()
应用程序一般是立即响应的,即不需要按回车就立即回应的,这种模式叫cbreak模式,相反的常用的模式是缓冲输入模式。开启立即cbreak模式代码如下:
curses.cbreak()
终端经常返回特殊键作为一个多字节的转义序列,比如光标键,或者导航键比如Page UP和Home键 。curses可以针对这些序列做一次处理,比如curses.KEY_LEFT返回一个特殊的值。要完成这些工作,必须开启键盘模式:
stdscr.keypad(1)
关闭curses非常简单,如下:
curses.nocbreak()#关闭字符终端功能(只有回车时才发生终端)
stdscr.keypad(0)
curses.echo() #打开输入回显功能
调用endwin()恢复默认设置
curses.endwin()
调试curses时常见的问题就是curses应用程序结束后没有重置终端到之前的状态,把终端弄的一团糟。比如键盘敲入字符后屏幕不回显,这让shell用起来非常困难。只能非常fuck的使用Ctrl-D结束;
所以curses提供了一种方便的方法,curses.wrapper(func)即可使用提供默认参数的curses,wrapper代码如下:
"""curses.wrapper
Contains one function, wrapper(), which runs another function which
should be the rest of your curses-based application. If the
application raises an exception, wrapper() will restore the terminal
to a sane state so you can read the resulting traceback.
"""
import curses
def wrapper(func, *args, **kwds):
"""Wrapper function that initializes curses and calls another function,
restoring normal keyboard/screen behavior on error.
The callable object 'func' is then passed the main window 'stdscr'
as its first argument, followed by any other arguments passed to
wrapper().
"""
try:
# Initialize curses
stdscr = curses.initscr()
# Turn off echoing of keys, and enter cbreak mode,
# where no buffering is performed on keyboard input
curses.noecho()
curses.cbreak()
# In keypad mode, escape sequences for special keys
# (like the cursor keys) will be interpreted and
# a special value like curses.KEY_LEFT will be returned
stdscr.keypad(1)
# Start color, too. Harmless if the terminal doesn't have
# color; user can test with has_color() later on. The try/catch
# works around a minor bit of over-conscientiousness in the curses
# module -- the error return from C start_color() is ignorable.
try:
curses.start_color()
except:
pass
return func(stdscr, *args, **kwds)
finally:
# Set everything back to normal
if 'stdscr' in locals():
stdscr.keypad(0)
curses.echo()
curses.nocbreak()
curses.endwin()
# -*- coding: UTF-8 -*-
import curses
def display_info(stdscr, str, x, y, colorpair=2):
'''使用指定的colorpair显示文字'''
stdscr.addstr(y, x, str, curses.color_pair(colorpair))
stdscr.refresh()
def get_ch_and_continue(stdscr):
'''演示press any key to continue'''
display_info(stdscr, 'Press any key to continue...', 0, 10)
# 设置nodelay,为0时会变成阻塞式等待
stdscr.nodelay(0)
# 输入一个字符
ch = stdscr.getch()
# 重置nodelay,使得控制台可以以非阻塞的方式接受控制台输入,超时1秒
stdscr.nodelay(1)
return True
def set_curses_color(stdscr):
'''控制台设置'''
# 使用颜色首先需要调用这个方法
curses.start_color()
# 文字和背景色设置,设置了两个color pair,分别为1和2
curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
if __name__ == '__main__':
# curses.wrapper(display_info, 'Hola, curses!', 0, 5)
# display_info('Hola, curses!', 0, 5)
# display_info('Press any key to continue...', 0, 10)
curses.wrapper(set_curses_color)
curses.wrapper(get_ch_and_continue)
三:例子
# -*- coding: UTF-8 -*-
import curses
stdscr = curses.initscr()
def display_info(str, x, y, colorpair=2):
'''使用指定的colorpair显示文字'''
global stdscr
stdscr.addstr(y, x, str, curses.color_pair(colorpair))
stdscr.refresh()
def get_ch_and_continue():
'''演示press any key to continue'''
global stdscr
# 设置nodelay,为0时会变成阻塞式等待
stdscr.nodelay(0)
# 输入一个字符
ch = stdscr.getch()
# 重置nodelay,使得控制台可以以非阻塞的方式接受控制台输入,超时1秒
stdscr.nodelay(1)
return True
def set_win():
'''控制台设置'''
global stdscr
# 使用颜色首先需要调用这个方法
curses.start_color()
# 文字和背景色设置,设置了两个color pair,分别为1和2
curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
# 关闭屏幕回显
curses.noecho()
# 输入时不需要回车确认
curses.cbreak()
# 设置nodelay,使得控制台可以以非阻塞的方式接受控制台输入,超时1秒
stdscr.nodelay(1)
def unset_win():
'''控制台重置'''
global stdstr
# 恢复控制台默认设置(若不恢复,会导致即使程序结束退出了,控制台仍然是没有回显的)
curses.nocbreak()
stdscr.keypad(0)
curses.echo()
# 结束窗口
curses.endwin()
if __name__ == '__main__':
try:
set_win()
display_info('Hola, curses!', 0, 5)
display_info('Press any key to continue...', 0, 10)
get_ch_and_continue()
except Exception, e:
raise e
finally:
unset_win()