標籤:
python 中curses封裝了c語言的curses,把c中複雜部分簡單化,比如addstr(),mvaddstr(),mvwaddstr()合并成了一個addstr()方法。
一、文法入門1、開啟和關閉一個curses 應用程式
在任何代碼執行前都先要初始化curses。初始化操作就是調用initscr()函數,如下。該函數根據不同裝置返回一個window對象代表整個螢幕,這個window對象通常叫做stdscr,和c語言報錯一致。
import cursesstdscr = 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應用程式結束後沒有重設終端到之前的狀態,把終端弄的一團糟。python中該問題經常是因為代碼有bug,發送異常引起的。比如鍵盤敲入字元後螢幕不回顯,這讓shell用起來非常困難。
為了避免這樣的問題,可以匯入curses.wrapper模組。這個函數做了一些初始化的工作,包括上面提到的和顏色的初始化。然後再執行你提供的函數,最後重設。而且被調用的函數寫在try-catch中。
2、開啟新視窗和pad
通常調用initscr()擷取一個window對象代表全部螢幕。但是很多程式希望劃分螢幕為幾個小的視窗,為了重繪,擦出這些工作在小視窗中獨立進行。newwin()函數就是用來建立一個新的視窗,需要給定視窗尺寸,並返回新的window對象的。
begin_x = 20; begin_y = 7height = 5; width = 40win = curses.newwin(height, width, begin_y, begin_x)
注意:座標通過是先y後x。這和別的座標系統不同,但是根深蒂固,寫的時候就這樣現在改太晚嘍。
當調用一個方法去顯示或者擦除文本時,效果不會立即顯示。 為了減少螢幕重繪的時間,curses就先累積這些操作,用一種更有效方式去顯示。就比如說你的程式先在視窗顯示了幾個字元,然後就清除螢幕,那就沒必要發送初始字元了,因為它們不會被顯示。
因此,curses需要你使用refresh()函數明確指出重繪視窗。
pad
pad是window的特例。pad可以比顯示的螢幕大,一次只顯示pad的一部分。建立一個pad很簡單,只需要提供寬高即可。但是重新整理pad需要提供螢幕上顯示的部分pad的座標。
pad = curses.newpad(100, 100)# These loops fill the pad with letters; this is# explained in the next sectionfor y in range(0, 100): for x in range(0, 100): try: pad.addch(y,x, ord(‘a‘) + (x*x+y*y) % 26) except curses.error: pass# Displays a section of the pad in the middle of the screenpad.refresh(0,0, 5,5, 20,75)
同時由多個window或者多個pad,有一問題:重新整理某個window或pad時螢幕會閃爍。
避免閃爍的方法:在每個window調用noutrefresh()方法。 然後使用refresh()方法的最後再調用doupdate()方法。
3、顯示文本
addscr不同格式如下:如果沒有座標,字元顯示在上一次操作完的位置。
Form |
Description |
str or ch |
Display the string str or character ch at the current position |
str or ch, attr |
Display the string str or character ch, using attribute attr at the current position |
y, x, str or ch |
Move to position y,x within the window, and display str or ch |
y, x, str or ch, attr |
Move to position y,x within the window, and display str or ch, using attribute attr |
屬性可以讓文本高亮顯示,比如黑體,底線,倒序,彩色顯示。
4、屬性和顏色
屬性和描述:
Attribute |
Description |
A_BLINK |
Blinking text |
A_BOLD |
Extra bright or bold text |
A_DIM |
Half bright text |
A_REVERSE |
Reverse-video text |
A_STANDOUT |
The best highlighting mode available |
A_UNDERLINE |
Underlined text |
螢幕第一行reverse-video顯示。
stdscr.addstr(0, 0, "Current mode: Typing mode", curses.A_REVERSE)stdscr.refresh()
curses使用前景色彩和背景色,可通過color_pair()方法擷取一對顏色。
使用顏色對1顯示一行
stdscr.addstr("Pretty text", curses.color_pair(1))stdscr.refresh()
start_color()初始化了8中基本顏色:0:black, 1:red, 2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white。
init_pair(n,f,b)修改顏色對n,讓f為前景色彩,b為背景色。顏色對0天生的黑白色,不允許改。
比如:修改color1為紅色文本,白色背景:
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_WHITE)
使用:
stdscr.addstr(0,0, "RED ALERT!", curses.color_pair(1))
5、使用者輸入
擷取輸入一遍使用getch()方法,這個方法暫停等待使用者輸入,顯示用echo()方法。
getch()返回一個整數 ,在0到255之間,表示輸入字元的ASCII值。列印255的是些特殊字元,比如Page Up,Home。
代碼經常這樣寫
while 1: c = stdscr.getch() if c == ord(‘p‘): PrintDocument() elif c == ord(‘q‘): break # Exit the while() elif c == curses.KEY_HOME: x = y = 0
getstr()擷取一個字串。因為功能有限不常用。
curses.echo() # Enable echoing of characters# Get a 15-character string, with the cursor on the top lines = stdscr.getstr(0,0, 15)
二、例子
代碼如下:
#-*- coding: UTF-8 -*-import cursesstdscr = 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 Truedef 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()
執行:# python testcurses.py
三、排錯
報錯:
[[email protected] srv]# python curses.pyTraceback (most recent call last): File "curses.py", line 2, in <module> import curses File "/srv/curses.py", line 4, in <module> stdscr = curses.initscr()AttributeError: ‘module‘ object has no attribute ‘initscr‘
原因:因為我的檔案取名是curses.py,而系統也是用的curses.py,python執行時先從目前的目錄尋找,所以不能和系統檔案重名。
換個名字,比如改名為testcurses.py 就好了。
參考:
https://docs.python.org/2/howto/curses.html
本文作者starof,因知識本身在變化,作者也在不斷學習成長,文章內容也不定時更新,為避免誤導讀者,方便追根溯源,請諸位轉載註明出處:http://www.cnblogs.com/starof/p/4703820.html有問題歡迎與我討論,共同進步。
python curses使用