用 Python 進(jìn)行 Curses 編程?
- 作者
A.M. Kuchling, Eric S. Raymond
- 發(fā)布版本
2.04
摘要
本文檔介紹了如何使用 curses
擴(kuò)展模塊控制文本模式的顯示。
curses 是什么??
curses 庫(kù)為基于文本的終端提供了獨(dú)立于終端的屏幕繪制和鍵盤(pán)處理功能;這些終端包括 VT100,Linux 控制臺(tái)以及各種程序提供的模擬終端。顯示終端支持各種控制代碼以執(zhí)行常見(jiàn)的操作,例如移動(dòng)光標(biāo),滾動(dòng)屏幕和擦除區(qū)域。不同的終端使用相差很大的代碼,并且往往有自己的小怪癖。
在普遍使用圖形顯示的世界中,人們可能會(huì)問(wèn)“為什么自找要麻煩”?畢竟字符單元顯示終端確實(shí)是一種過(guò)時(shí)的技術(shù),但是在某些領(lǐng)域中,能夠用它們做花哨的事情仍然很有價(jià)值。一個(gè)小眾市場(chǎng)是在不運(yùn)行 X server 的小型或嵌入式 Unix 上。另一個(gè)是在提供圖形支持之前,可能需要運(yùn)行的工具,例如操作系統(tǒng)安裝程序和內(nèi)核配置程序。
curses 庫(kù)提供了相當(dāng)基礎(chǔ)的功能,為程序員提供了包含多個(gè)非重疊文本窗口的顯示的抽象。窗口的內(nèi)容可以通過(guò)多種方式更改---添加文本,擦除文本,更改其外觀---以及curses庫(kù)將確定需要向終端發(fā)送哪些控制代碼以產(chǎn)生正確的輸出。 curses并沒(méi)有提供諸多用戶界面概念,例如按鈕,復(fù)選框或?qū)υ捒?。如果需要這些功能,請(qǐng)考慮用戶界面庫(kù),例如 Urwid 。
curses 庫(kù)最初是為BSD Unix 編寫(xiě)的。 后來(lái) AT&T 的Unix System V 版本加入了許多增強(qiáng)功能和新功能。如今BSD curses已不再維護(hù),被ncurses取代,ncurses是 AT&T 接口的開(kāi)源實(shí)現(xiàn)。如果使用的是 Linux 或 FreeBSD 等開(kāi)源Unix系統(tǒng),則幾乎肯定會(huì)使用ncurses。由于大多數(shù)當(dāng)前的商業(yè)Unix版本都基于System V代碼,因此這里描述的所有功能可能都可用。但是,某些專有Unix所帶來(lái)的較早版本的curses可能無(wú)法支持所有功能。
The Windows version of Python doesn't include the curses
module. A ported version called UniCurses is available.
Python 的 curses 模塊?
此 Python 模塊相當(dāng)簡(jiǎn)單地封裝了 curses 提供的 C 函數(shù);如果你已經(jīng)熟悉在 C 語(yǔ)言中使用 curses 編程,把這些知識(shí)轉(zhuǎn)移的 Python 是非常容易的。最大的差異在于 Python 中的接口通過(guò)把不同的 C 函數(shù)合并來(lái)讓事情變得更簡(jiǎn)單,比如 addstr()
、mvaddstr()
和 mvwaddstr()
三個(gè) C 函數(shù)被并入 addstr()
這一個(gè)方法。下文中會(huì)描述更多的細(xì)節(jié)。
本 HOWTO 是關(guān)于使用 curses 和 Python 編寫(xiě)文本模式程序的概述。它并不被設(shè)計(jì)為一個(gè) curses API 的完整指南;如需完整指南,請(qǐng)參見(jiàn) ncurses 的 Python 庫(kù)指南章節(jié)和 ncurses 的 C 手冊(cè)頁(yè)。相對(duì)地,本 HOWTO 將會(huì)給你一些基本思路。
開(kāi)始和結(jié)束 curses 應(yīng)用程序?
在做任何事情之前,curses 必須先被初始化。可以通過(guò)調(diào)用函數(shù) initscr()
來(lái)實(shí)現(xiàn),它將查明終端的類型,向終端發(fā)送任何必須的設(shè)置代碼,并創(chuàng)建多種內(nèi)部數(shù)據(jù)結(jié)構(gòu)。如果此操作成功,initscr()
將會(huì)返回一個(gè)代表整個(gè)屏幕的窗口對(duì)象;它通常會(huì)遵循對(duì)應(yīng)的 C 變量名被稱作 stdscr
:
import curses
stdscr = curses.initscr()
使用 curses 的應(yīng)用程序通常會(huì)關(guān)閉按鍵自動(dòng)上屏,目的是讀取按鍵并只在特定情況下展示它們。這需要調(diào)用函數(shù) noecho()
:
curses.noecho()
應(yīng)用程序也會(huì)廣泛地需要立即響應(yīng)按鍵,而不需要按下回車鍵;這被稱為 “cbreak” 模式,與通常的緩沖輸入模式相對(duì):
curses.cbreak()
終端通常會(huì)以多字節(jié)轉(zhuǎn)義序列的形式返回特殊按鍵,比如光標(biāo)鍵和導(dǎo)航鍵比如 Page Up 鍵和 Home 鍵。盡管你可以編寫(xiě)你的程序來(lái)應(yīng)對(duì)這些序列,curses 能夠代替你做到這件事,返回一個(gè)特殊值比如 curses.KEY_LEFT
。為了讓 curses 做這項(xiàng)工作,你需要啟用 keypad 模式:
stdscr.keypad(True)
終止一個(gè) curses 應(yīng)用程序比建立一個(gè)容易得多,你只需要調(diào)用:
curses.nocbreak()
stdscr.keypad(False)
curses.echo()
來(lái)還原對(duì)終端作出的 curses 友好設(shè)置。然后,調(diào)用函數(shù) endwin()
來(lái)將終端還原到它的原始操作模式:
curses.endwin()
調(diào)試一個(gè) curses 應(yīng)用程序時(shí)常會(huì)發(fā)生,一個(gè)應(yīng)用程序還未能還原終端到原本的狀態(tài)就意外退出了,這會(huì)攪亂你的終端。在 Python 中這常常會(huì)發(fā)生在你的代碼中有 bug 并引發(fā)了一個(gè)未捕獲的異常。當(dāng)你嘗試輸入時(shí)按鍵不會(huì)上屏,這使得使用終端變得困難。
在 Python 中你可以避免這些復(fù)雜問(wèn)題并讓調(diào)試變得更簡(jiǎn)單,只需要導(dǎo)入 curses.wrapper()
函數(shù)并像這樣使用它:
from curses import wrapper
def main(stdscr):
# Clear screen
stdscr.clear()
# This raises ZeroDivisionError when i == 10.
for i in range(0, 11):
v = i-10
stdscr.addstr(i, 0, '10 divided by {} is {}'.format(v, 10/v))
stdscr.refresh()
stdscr.getkey()
wrapper(main)
函數(shù) wrapper()
接受一個(gè)可調(diào)用對(duì)象并首先進(jìn)行上述初始化過(guò)程,在終端支持著色時(shí)還會(huì)初始化顏色。接著 wrapper()
運(yùn)行你提供的可調(diào)用對(duì)象。當(dāng)該可調(diào)用對(duì)象返回時(shí),wrapper()
會(huì)還原終端到初始狀態(tài)。該可調(diào)用對(duì)象會(huì)在 try
...except
這樣的結(jié)構(gòu)內(nèi)被調(diào)用,當(dāng)它捕獲到異常時(shí),會(huì)先還原終端再重新引發(fā)這個(gè)異常。所以你的終端不會(huì)因?yàn)楫惓6涣粼谝粋€(gè)搞笑的狀態(tài),你也可以正常閱讀異常消息和回溯信息。
窗口和面板?
窗口是 curses 中的基本抽象。一個(gè)窗口對(duì)象表示了屏幕上的一個(gè)矩形區(qū)域,并且提供方法來(lái)顯示文本、擦除文本、允許用戶輸入字符串等等。
函數(shù) initscr()
返回的 stdscr
對(duì)象覆蓋整個(gè)屏幕。許多程序可能只需要這一個(gè)窗口,但你可能希望把屏幕分割為多個(gè)更小的窗口,來(lái)分別重繪或者清除它們。函數(shù) newwin()
根據(jù)給定的尺寸創(chuàng)建一個(gè)新窗口,并返回這個(gè)新的窗口對(duì)象:
begin_x = 20; begin_y = 7
height = 5; width = 40
win = curses.newwin(height, width, begin_y, begin_x)
注意 curses 使用的坐標(biāo)系統(tǒng)與尋常的不同。坐標(biāo)始終是以 y,x 的順序傳遞,并且左上角是坐標(biāo) (0,0)。這打破了正常的坐標(biāo)處理約定,即 x 坐標(biāo)在前。這是一個(gè)與其他計(jì)算機(jī)應(yīng)用程序糟糕的差異,但這從 curses 最初被編寫(xiě)出來(lái)就已是它的一部分,現(xiàn)在想要修改它已為時(shí)已晚。
你的應(yīng)用程序能夠查明屏幕的尺寸,curses.LINES
和 curses.COLS
分別代表了 y 和 x 方向上的尺寸。合理的坐標(biāo)應(yīng)位于 (0,0)
到 (curses.LINES - 1, curses.COLS - 1)
范圍內(nèi)。
當(dāng)你調(diào)用一個(gè)方法來(lái)顯示或擦除文本時(shí),效果并不會(huì)立即顯示。相反,你必須調(diào)用窗口對(duì)象的 refresh()
方法來(lái)更新屏幕。
這是因?yàn)?curses 最初是為 300 波特的龜速終端連接編寫(xiě)的;在這些終端上,壓制重繪屏幕的時(shí)間就非常重要。相對(duì)地,當(dāng)你調(diào)用 refresh()
時(shí),curses 會(huì)累積屏幕的修改并以效率最高的方式顯示它們。打個(gè)比方,如果你的程序在一個(gè)窗口內(nèi)顯示一些文本然后清楚了這個(gè)窗口,那么這些原始文本不需要被發(fā)送,因?yàn)樗鼈兩踔敛辉鼙豢匆?jiàn)。
在實(shí)踐中,顯式地告訴 curses 來(lái)重繪一個(gè)窗口并不會(huì)太復(fù)雜化 curses 編程。大部分程序會(huì)顯示一堆內(nèi)容然后等待按鍵或者其他某些用戶側(cè)動(dòng)作。你要做的事情就是,保證屏幕在暫停并等待用戶輸入前被重繪,只需要先調(diào)用 stdscr.refresh()
或者其他相關(guān)窗口的 refresh()
方法。
一個(gè)面板是一種特殊的窗口,它可以比實(shí)際的顯示屏幕更大,并且能只顯示它的一部分。創(chuàng)建面板需要指定面板的高度和寬度,但刷新一個(gè)面板需要給出屏幕坐標(biāo)和面板的需要顯示的局部。
pad = curses.newpad(100, 100)
# These loops fill the pad with letters; addch() is
# explained in the next section
for y in range(0, 99):
for x in range(0, 99):
pad.addch(y,x, ord('a') + (x*x+y*y) % 26)
# Displays a section of the pad in the middle of the screen.
# (0,0) : coordinate of upper-left corner of pad area to display.
# (5,5) : coordinate of upper-left corner of window area to be filled
# with pad content.
# (20, 75) : coordinate of lower-right corner of window area to be
# : filled with pad content.
pad.refresh( 0,0, 5,5, 20,75)
此 refresh()
調(diào)用會(huì)在屏幕坐標(biāo) (5,5) 到坐標(biāo) (20,75) 的矩形范圍內(nèi)顯示面板的一個(gè)部分,被顯示的部分在面板上的坐標(biāo)是 (0,0)。除了上述差異,面板與常規(guī)的窗口相同,也支持相同的方法。
如果你在屏幕上有多個(gè)窗口和面板,有一個(gè)更有效率的方法來(lái)更新窗口,避免每個(gè)部分單獨(dú)更新時(shí)煩人的屏幕閃爍。refresh()
實(shí)際上做了兩件事:
調(diào)用每個(gè)窗口的
noutrefresh()
方法來(lái)更新一個(gè)表達(dá)屏幕期望狀態(tài)的底層的數(shù)據(jù)結(jié)構(gòu)。調(diào)用函數(shù)
doupdate()
來(lái)改變物理屏幕來(lái)符合這個(gè)數(shù)據(jù)結(jié)構(gòu)中記錄的期望狀態(tài)。
你可以改為調(diào)用在多個(gè)窗口上 noutrefresh()
方法來(lái)更新該數(shù)據(jù)結(jié)構(gòu),然后調(diào)用函數(shù) doupdate()
來(lái)更新屏幕。
顯示文字?
從一名 C 語(yǔ)言程序員的視角來(lái)看,curses 有時(shí)看起來(lái)就像是一堆略有差異的函數(shù)組成的扭曲迷宮。舉個(gè)例子,addstr()
在 stdscr
窗口的當(dāng)前光標(biāo)位置顯示一個(gè)字符串,而 mvaddstr()
則是先移動(dòng)到一個(gè)給定的 y,x 坐標(biāo)再顯示字符串。waddstr()
與 addstr()
類似,但允許指定一個(gè)窗口而非默認(rèn)的 stdscr
。mvwaddstr()
允許同時(shí)指定一個(gè)窗口和一個(gè)坐標(biāo)。
幸運(yùn)的是,Python 接口隱藏了所有這些細(xì)節(jié)。stdscr
和其他任何窗口一樣是一個(gè)窗口對(duì)象,并且諸如 addstr()
之類的方法接受多種參數(shù)形式。通常有四種形式。
形式 |
描述 |
---|---|
str 或 ch |
在當(dāng)前位置顯示字符串 str 或字符 ch |
str 或 ch, attr |
在當(dāng)前位置使用 attr 屬性顯示字符串 str 或字符 ch |
y, x, str 或 ch |
移動(dòng)到窗口內(nèi)的 y,x 位置,并顯示 str 或 ch |
y, x, str 或 ch, attr |
移至窗口內(nèi)的 y,x 位置,并使用 attr 屬性顯示 str 或 ch |
屬性允許以突出顯示形態(tài)顯示文本,比如加粗、下劃線、反相或添加顏色。這些屬性將來(lái)下一小節(jié)細(xì)說(shuō)。
The addstr()
method takes a Python string or
bytestring as the value to be displayed. The contents of bytestrings
are sent to the terminal as-is. Strings are encoded to bytes using
the value of the window's encoding
attribute; this defaults to
the default system encoding as returned by locale.getencoding()
.
方法 addch()
接受一個(gè)字符,可以是長(zhǎng)度為 1 的字符串,長(zhǎng)度為 1 的字節(jié)串或者一個(gè)整數(shù)。
對(duì)于特殊擴(kuò)展字符有一些常量,這些常量是大于 255 的整數(shù)。比如,ACS_PLMINUS
是一個(gè) “加減” 符號(hào),ACS_ULCORNER
是一個(gè)框的左上角(方便繪制邊界)。你也可以使用正確的 Unicode 字符。
窗口會(huì)記住上次操作之后光標(biāo)所在位置,所以如果你忽略 y,x 坐標(biāo),字符串和字符會(huì)出現(xiàn)在上次操作結(jié)束的位置。你也可以通過(guò) move(y,x)
的方法來(lái)移動(dòng)光標(biāo)。因?yàn)橐恍┙K端始終會(huì)顯示一個(gè)閃爍的光標(biāo),你可能會(huì)想要保證光標(biāo)處于一些不會(huì)讓人感到分心的位置。在看似隨機(jī)的位置出現(xiàn)一個(gè)閃爍的光標(biāo)會(huì)令人非常迷惑。
如果你的應(yīng)用程序完全不需要一個(gè)閃爍的光標(biāo),你可以調(diào)用 curs_set(False)
來(lái)使它隱形。為與舊版本 curses 的兼容性的關(guān)系,有函數(shù) leaveok(bool)
作為 curs_set()
的等價(jià)替換。如果 bool 是真值,curses 庫(kù)會(huì)嘗試移除閃爍光標(biāo),并且你也不必?fù)?dān)心它會(huì)留在一些奇怪的位置。
屬性和顏色?
字符可以以不同的方式顯示。基于文本的應(yīng)用程序常常以反相顯示狀態(tài)行,一個(gè)文本查看器可能需要突出顯示某些單詞。為了支持這種用法,curses 允許你為屏幕上的每個(gè)單元指定一個(gè)屬性值。
屬性值是一個(gè)整數(shù),它的每一個(gè)二進(jìn)制位代表一個(gè)不同的屬性。你可以嘗試以多種不屬性位組合來(lái)顯示文本,但 curses 不保證所有的組合都是有效的,或者看上去有明顯不同。這一點(diǎn)取決于用戶終端的能力,所以最穩(wěn)妥的方式是只采用最常見(jiàn)的有效屬性,見(jiàn)下表。
屬性 |
描述 |
---|---|
|
閃爍文本 |
|
超亮或粗體文本 |
|
半明亮文本 |
|
反相顯示文本 |
|
可用的最佳突出顯示模式 |
|
帶下劃線的文本 |
所以,為了在屏幕頂部顯示一個(gè)反相的狀態(tài)行,你可以這么編寫(xiě):
stdscr.addstr(0, 0, "Current mode: Typing mode",
curses.A_REVERSE)
stdscr.refresh()
curses 庫(kù)還支持在提供了顏色功能的終端上顯示顏色的功能。最常見(jiàn)的提供顏色的終端很可能是 Linux 控制臺(tái),采用了 xterms 配色方案。
為了使用顏色,你必須在調(diào)用完函數(shù) initscr()
后盡快調(diào)用函數(shù) start_color()
,來(lái)初始化默認(rèn)顏色集 (curses.wrapper()
函數(shù)自動(dòng)完成了這一點(diǎn))。 當(dāng)它完成后,如果使用中的終端支持顯示顏色, has_colors()
會(huì)返回真值。 (注意:curses 使用美式拼寫(xiě) “color”,而不是英式/加拿大拼寫(xiě) “colour”。如果你習(xí)慣了英式拼寫(xiě),你需要避免自己在這些函數(shù)上拼寫(xiě)錯(cuò)誤。)
curses 庫(kù)維護(hù)一個(gè)有限數(shù)量的顏色對(duì),包括一個(gè)前景(文本)色和一個(gè)背景色。你可以使用函數(shù) color_pair()
獲得一個(gè)顏色對(duì)對(duì)應(yīng)的屬性值。它可以通過(guò)按位或運(yùn)算與其他屬性,比如 A_REVERSE
組合。但再說(shuō)明一遍,這種組合并不保證在所有終端上都有效。
一個(gè)樣例,用 1 號(hào)顏色對(duì)顯示一行文本:
stdscr.addstr("Pretty text", curses.color_pair(1))
stdscr.refresh()
如前所述, 顏色對(duì)由前景色和背景色組成。 init_pair(n, f, b)
函數(shù)可改變顏色對(duì) n 的定義 為前景色 f 和背景色 b。 顏色對(duì) 0 硬編碼為黑底白字,不能改變。
顏色已經(jīng)被編號(hào),并且當(dāng)其激活 color 模式時(shí) start_color()
會(huì)初始化 8 種基本顏色。 它們是: 0:black, 1:red, 2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan 和 7:white。 curses
模塊為這些顏色定義了相應(yīng)的名稱常量: curses.COLOR_BLACK
, curses.COLOR_RED
等等。
讓我們來(lái)做個(gè)綜合練習(xí)。 要將顏色 1 改為紅色文本白色背景,你應(yīng)當(dāng)調(diào)用:
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_WHITE)
當(dāng)你改變一個(gè)顏色對(duì)時(shí),任何已經(jīng)使用該顏色對(duì)來(lái)顯示的文本將會(huì)更改為新的顏色。 你還可以這樣來(lái)顯示新顏色的文本:
stdscr.addstr(0,0, "RED ALERT!", curses.color_pair(1))
某些非?;ㄉ诘慕K端可以將實(shí)際顏色定義修改為給定的 RGB 值。 這允許你將通常為紅色的 1 號(hào)顏色改成紫色或藍(lán)色或者任何你喜歡的顏色。 不幸的是,Linux 控制臺(tái)不支持此特性,所以我無(wú)法嘗試它,也無(wú)法提供任何示例。 想要檢查你的終端是否能做到你可以調(diào)用 can_change_color()
,如果有此功能則它將返回 True
。 如果你幸運(yùn)地?fù)碛幸粋€(gè)如此優(yōu)秀的終端,請(qǐng)查詢你的系統(tǒng)的幫助頁(yè)面來(lái)了解詳情。
用戶輸入?
C curses 庫(kù)提供了非常簡(jiǎn)單的輸入機(jī)制。 Python 的 curses
模塊添加了一個(gè)基本的文本輸入控件。 (其他的庫(kù)例如 Urwid 擁有更豐富的控件集。)
有兩個(gè)方法可以從窗口獲取輸入:
getch()
會(huì)刷新屏幕然后等待用戶按鍵,如果之前調(diào)用過(guò)echo()
還會(huì)顯示所按的鍵。 你還可以選擇指定一個(gè)坐標(biāo)以便在暫停之前讓光標(biāo)移動(dòng)到那里。getkey()
將做同樣的事但是會(huì)把整數(shù)轉(zhuǎn)換為字符串。 每個(gè)字符將返回為長(zhǎng)度為 1 個(gè)字符的字符串,特殊鍵例如函數(shù)鍵將返回包含鍵名的較長(zhǎng)字符串例如KEY_UP
或^G
。
使用 nodelay()
窗口方法可以做到不等待用戶。 在 nodelay(True)
之后,窗口的 getch()
和 getkey()
將成為非阻塞的。 為表明輸入未就緒,getch()
會(huì)返回 curses.ERR
(值為 -1) 而 getkey()
會(huì)引發(fā)異常。 此外還有 halfdelay()
函數(shù),它可被用來(lái)(實(shí)際地)在每個(gè) getch()
上設(shè)置一個(gè)計(jì)時(shí)器;如果在指定的延遲內(nèi)沒(méi)有輸入可用(以十分之一秒為單位),curses 將引發(fā)異常。
getch()
方法返回一個(gè)整數(shù);如果數(shù)值在 0 到 255 之間,它代表所按下鍵的 ASCII 碼。 大于 255 的值為特殊鍵例如 Page Up, Home 或方向鍵等。 你可以將返回的值與 curses.KEY_PPAGE
, curses.KEY_HOME
或 curses.KEY_LEFT
等常量做比較。 你的程序主循環(huán)看起來(lái)可能是這樣:
while True:
c = stdscr.getch()
if c == ord('p'):
PrintDocument()
elif c == ord('q'):
break # Exit the while loop
elif c == curses.KEY_HOME:
x = y = 0
curses.ascii
模塊提供了一些 ASCII 類成員函數(shù),它們接受整數(shù)或長(zhǎng)度為 1 個(gè)字符的字符串參數(shù);這些函數(shù)在為這樣的循環(huán)編寫(xiě)更具可讀性的測(cè)試時(shí)可能會(huì)很有用。 它還提供了一些轉(zhuǎn)換函數(shù),它們接受整數(shù)或長(zhǎng)度為 1 個(gè)字符的字符串參數(shù)并返回同樣的類型。 例如,curses.ascii.ctrl()
返回與其參數(shù)相對(duì)應(yīng)的控制字符。
還有一個(gè)可以提取整個(gè)字符串的方法 getstr()
。 它并不經(jīng)常被使用,因?yàn)樗墓δ芟喈?dāng)受限;可用的編輯鍵只有 Backspace 和 Enter 鍵,它們會(huì)結(jié)束字符串。 也可以選擇限制為固定數(shù)量的字符。
curses.echo() # Enable echoing of characters
# Get a 15-character string, with the cursor on the top line
s = stdscr.getstr(0,0, 15)
curses.textpad
模塊提供了一個(gè)文本框,它支持類似 Emacs 的鍵綁定集。 Textbox
類的各種方法支持帶輸入驗(yàn)證的編輯及包含或不包含末尾空格地收集編輯結(jié)果。 下面是一個(gè)例子:
import curses
from curses.textpad import Textbox, rectangle
def main(stdscr):
stdscr.addstr(0, 0, "Enter IM message: (hit Ctrl-G to send)")
editwin = curses.newwin(5,30, 2,1)
rectangle(stdscr, 1,0, 1+5+1, 1+30+1)
stdscr.refresh()
box = Textbox(editwin)
# Let the user edit until Ctrl-G is struck.
box.edit()
# Get resulting contents
message = box.gather()
請(qǐng)查看 curses.textpad
的庫(kù)文檔了解更多細(xì)節(jié)。
更多的信息?
本 HOWTO 沒(méi)有涵蓋一些進(jìn)階主題,例如讀取屏幕的內(nèi)容或從 xterm 實(shí)例捕獲鼠標(biāo)事件等,但是 curses
模塊的 Python 庫(kù)文檔頁(yè)面現(xiàn)在已相當(dāng)完善。 接下來(lái)你應(yīng)當(dāng)去瀏覽一下其中的內(nèi)容。
如果你對(duì) curses 函數(shù)的細(xì)節(jié)行為有疑問(wèn),請(qǐng)查看你的 curses 實(shí)現(xiàn)版本的說(shuō)明頁(yè)面,不論它是 ncurses 還是特定 Unix 廠商的版本。 說(shuō)明頁(yè)面將記錄任何具體問(wèn)題,并提供所有函數(shù)、屬性以及可用 ACS_*
字符的完整列表。
由于 curses API 是如此的龐大,某些函數(shù)并不被 Python 接口所支持。 這往往不是因?yàn)樗鼈冸y以實(shí)現(xiàn),而是因?yàn)檫€沒(méi)有人需要它們。 此外,Python 尚不支持與 ncurses 相關(guān)聯(lián)的菜單庫(kù)。 歡迎提供添加這些功能的補(bǔ)?。徽?qǐng)參閱 Python 開(kāi)發(fā)者指南 了解有關(guān)為 Python 提交補(bǔ)丁的詳情。
使用 NCURSES 編寫(xiě)程序: 一篇面向 C 程序員的詳細(xì)教程。
ncurses 手冊(cè)主頁(yè) <https://linux.die.net/man/3/ncurses>`_
ncurses 常見(jiàn)問(wèn)題 <http://invisible-island.net/ncurses/ncurses.faq.html>`_
"使用 curses... 請(qǐng)勿爆粗": 一場(chǎng)有關(guān)使用 curses 或 Urwid 來(lái)控制終端的 PyCon 2013 演講的視頻。
"使用 Urwid 的控制臺(tái)應(yīng)用程序": 一場(chǎng)演示使用 Urwid 編寫(xiě)應(yīng)用程序的 PyCon CA 2012 演講的視頻。