Python-Curses模块
Python-Curses
- 什么是Curses?
- Python Curses模块
- 开始我们的编程吧(启动与结束)
- 重要使用方法(包装用法)
- Windows and Pads
- 显示文本
- 属性和颜色
- 用户输入
什么是Curses?
curses库为基于文本的终端提供独立于终端的屏幕绘制和键盘处理设施;这些终端包括VT100s、Linux控制台和各种程序提供的模拟终端。显示终端支持各种控制代码来执行常见的操作,如移动光标、滚动屏幕和擦除区域。不同的终端使用的代码差别很大,而且常常有自己的小毛病。
在图形显示的世界中,有人可能会问“为什么要这么麻烦”?诚然,字符单元显示终端是一种过时的技术,但在某些特定领域,能够用它们做一些新奇的事情仍然很有价值。其中一个利基市场是不运行X服务器的占用空间小或嵌入式unix。另一个是OS安装程序和内核配置器等工具,它们可能必须在任何图形支持可用之前运行。
curses库提供了相当基本的功能,为程序员提供了一个包含多个非重叠文本窗口的显示抽象。窗口的内容可以通过各种方式进行更改——添加文本、擦除文本、更改外观——curses库将计算出需要将哪些控制代码发送到终端才能生成正确的输出。curses没有提供许多用户界面概念,比如按钮、复选框或对话框;如果需要这些特性,可以考虑使用用户界面库,比如Urwid。
curses库最初是为BSD Unix编写的;AT&T后来的System V版本Unix增加了许多增强功能和新功能。不再维护BSD curses,取而代之的是ncurses,它是AT&T接口的一个开源实现。如果您使用的是开源Unix,比如Linux或FreeBSD,那么您的系统几乎肯定使用了ncurses。由于目前大多数商业Unix版本都基于System V代码,所以这里描述的所有函数可能都是可用的。不过,一些专有的Unixes携带的旧版本的咒语可能并不支持所有的功能。
Windows版本的Python不包含curses模块。一个名为UniCurses的移植版本是可用的。您还可以尝试Fredrik Lundh编写的控制台模块,它不使用与curses相同的API,但提供了可通过指针寻址的文本输出,并完全支持鼠标和键盘输入。
Python Curses模块
本教程介绍如何使用curses和Python编写文本模式的程序。它并不是curses API的完整指南;为此,请参阅Python库指南中关于ncurses的部分,以及关于ncurses的C手册页面。不过,它会给你一些基本的概念。
开始我们的编程吧(启动与结束)
初始化curses:
import curses
stdscr = curses.initscr()
通常使用noecho()使屏幕停止输出无关内容:
curses.noecho()
应用程序通常也需要立即响应键,而不需要按Enter键;这称为cbreak模式,与通常的缓冲输入模式相反。
curses.cbreak()
终端通常返回特殊的键,如光标键或导航键,如Page Up和Home,作为多字节转义序列。虽然您可以编写应用程序来期望这样的序列并相应地处理它们,但是curses可以为您做到这一点,返回一个特殊的值,比如curss . key_left。要让Curses生效,你必须启用键盘模式。
stdscr.keypad(True)
终止curses应用程序要比启动curses应用程序容易得多。你需要调用:
相对于,启动,终止只需要反向操作:
curses.nocbreak()
stdscr.keypad(False)
curses.echo()
反转对curses友好的终端设置。然后调用endwin()函数将终端恢复到原来的操作模式。
curses.endwin()
在调试一个cruses应用程序时,一个常见的问题是,当应用程序死亡而没有将终端恢复到以前的状态时,您的终端就会陷入混乱。在Python中,这通常发生在代码有bug并引发未捕获异常时。例如,当您键入键时,键不再回显到屏幕,这使得使用shell变得困难。
重要使用方法(包装用法)
在Python中,您可以通过导入curses .wrapper()函数并像这样使用它来避免这些复杂性,并使调试变得更加容易:
from curses import wrapperdef main(stdscr):# Clear screenstdscr.clear()# This raises ZeroDivisionError when i == 10.for i in range(0, 11):v = i-10stdscr.addstr(i, 0, '10 divided by {} is {}'.format(v, 10/v))stdscr.refresh()stdscr.getkey()wrapper(main)
包装器()函数接受一个可调用对象并执行上面描述的初始化,如果有颜色支持,还初始化颜色。然后运行您提供的可调用的wrapper()。一旦可调用返回,wrapper()将恢复终端的原始状态。可调用的对象在try中被调用,但它捕获异常,恢复终端的状态,然后重新引发异常。因此,您的终端将不会在异常上处于奇怪的状态,您将能够读取异常的消息并进行回溯。
Windows and Pads
窗口的cruses的基本抽象。窗口对象表示屏幕的矩形区域,并支持显示文本、擦除文本、允许用户输入字符串等方法。
函数initscr()返回的stdscr对象是一个覆盖整个屏幕的窗口对象。许多程序可能只需要这个窗口,但是您可能希望将屏幕分割成更小的窗口,以便分别重新绘制或清除它们。newwin()函数的作用是:创建一个给定大小的新窗口,返回新窗口对象。
begin_x = 20; begin_y = 7
height = 5; width = 40
win = curses.newwin(height, width, begin_y, begin_x)
注意,在cruses中使用的坐标系是不寻常的。坐标总是以y,x的顺序传递,窗口的左上角是坐标(0,0)。这打破了处理首先出现x坐标的坐标的常规。这与大多数其他计算机应用程序有一个不幸的不同之处,但自从它最初被编写以来,它就一直是cruses的一部分,现在要改变已经太迟了。
当您调用一个方法来显示或擦除文本时,效果不会立即显示在屏幕上。
相反,您必须调用window对象的refresh()方法来更新屏幕。
这是因为cruses最初是在300波特的终端连接速度较慢的情况下编写的;使用这些终端,最小化重绘屏幕所需的时间是非常重要的。相反,curses会累积对屏幕的更改,并在调用refresh()时以最有效的方式显示更改。例如,如果您的程序在窗口中显示了一些文本,然后清除了该窗口,那么就不需要发送原始文本,因为它们永远不可见
实际上,显式地告诉curses重新绘制一个窗口并不会使使用curses进行编程变得非常复杂。大多数程序都进入忙乱状态,然后暂停,等待用户的一个按键或其他动作。在暂停等待用户输入之前,您所要做的就是确保屏幕已经重新绘制,方法是首先调用stdscr.refresh()或其他相关窗口的refresh()方法。
pad是Window的一种特殊情况;它可以比实际的显示屏大,而且一次只能显示pad的一部分。创建一个pad需要pad的高度和宽度,而刷新pad则需要给出屏幕上显示pad的一个小节的区域的坐标。
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()调用在屏幕上显示从坐标(5,5)扩展到坐标(20,75)的矩形中pad的一部分;显示部分的左上角是pad上的坐标(0,0)。除此之外,pad与普通窗口完全一样,支持相同的方法。
如果你在屏幕上有多个窗口和垫子,有一个更有效的方法来更新屏幕,防止烦人的屏幕闪烁,因为屏幕的每个部分都得到了更新。refresh()实际上做两件事:
- 调用每个窗口的noutrefresh()方法来更新表示屏幕所需状态的底层数据结构。
- 调用函数doupdate()函数来更改物理屏幕以匹配数据结构中记录的所需状态。
相反,您可以在多个窗口上调用noutrefresh()来更新数据结构,然后调用doupdate()来更新屏幕。
显示文本
在python中,只有一个函数addstr():
**参数格式:**一共有4种
- str or ch 显示string str 或者ch
- str or ch, attr 显示string 或者 ch,attr 在当前位置
- y, x, str or ch 一共位置到y,x然后打印出相应内容
- y, x, str or ch, attr 移动到y,x,打印内容,使用属性。
属性允许以突出显示的形式显示文本,如黑体、下划线、反向代码或颜色。它们将在下一小节中得到更详细的解释。
addstr()方法接受一个Python字符串或bytestring作为要显示的值。字节串的内容按原样发送到终端。使用窗口的编码属性值将字符串编码为字节;这默认为local .getpreferredencoding()返回的默认系统编码。
addch()方法接受一个字符,它可以是长度为1的字符串、长度为1的字节字符串或整数。
为扩展字符提供常量;这些常数是大于255的整数。例如,ACS_PLMINUS是+/-符号,ACS_ULCORNER是框的左上角(方便绘制边框)。您还可以使用适当的Unicode字符
Windows会记住上次操作后光标的位置,所以如果您省略了y、x坐标,则字符串或字符将显示在上次操作结束的位置。您还可以使用move(y,x)方法移动光标。因为一些终端总是显示闪烁的光标,所以您可能希望确保光标位于不会分散注意力的位置;光标在某些明显随机的位置闪烁可能会让人感到困惑。
leaveok(bool)/curs_set():函数用于关闭游标闪烁
如果应用程序根本不需要闪烁的光标,可以调用curs_set(False)使其不可见。为了与旧的curses版本兼容,有一个leaveok(bool)函数,它是curs_set()的同义词。当bool为真时,curses库将尝试抑制闪烁的光标,您无需担心将其放在奇怪的位置。
属性和颜色
字符可以以不同的方式显示。基于文本的应用程序中的状态行通常以反向视频的形式显示,或者文本查看器可能需要突出显示某些单词。curses支持这一点,它允许您为屏幕上的每个单元格指定一个属性。
属性是一个整数,每个位代表一个不同的属性。您可以尝试显示具有多个属性位集的文本,但是curses不能保证所有可能的组合都可用,或者它们在视觉上都是不同的。这取决于正在使用的终端的能力,因此最安全的方法是使用这里列出的最常用的属性。
- 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
因此,要在屏幕的顶部显示一个反向视频状态行,您可以编写代码:
stdscr.addstr(0, 0, "Current mode: Typing mode",curses.A_REVERSE)
stdscr.refresh()
curses库还支持在提供它的终端上使用颜色。最常见的此类终端可能是Linux控制台,其次是color xterms。
要使用color,必须在调用initscr()后不久调用start_color()函数,以初始化默认的颜色集(curses .wrapper()函数会自动执行此操作)。完成后,如果使用的终端可以显示颜色,那么has_colors()函数将返回TRUE。(注:curses使用美式拼写“color”,而不是加拿大/英国拼写“colour”。如果你已经习惯了英式拼写,那么为了这些功能,你就不得不承认自己拼错了。
curses库维护有限数量的颜色对,包括前景(或文本)颜色和背景颜色。可以使用color_pair()函数获得与颜色对对应的属性值;这可以与其他属性(如A_REVERSE)进行位操作或’ed,但是同样,这种组合不能保证在所有终端上都有效。
一个例子,它显示一行文本使用颜色对1:
stdscr.addstr("Pretty text", curses.color_pair(1))
stdscr.refresh()
init_pair(n, f, b)改变颜色对前景色、背景色。
如前所述,一对颜色由前景和背景颜色组成。init_pair(n, f, b)函数将颜色对n的定义更改为前景色f和背景色b。
让我们把这些放在一起。要将颜色1更改为白色背景上的红色文本,您可以调用:
stdscr.addstr(0,0, "RED ALERT!", curses.color_pair(1)
非常漂亮的终端可以将实际颜色的定义更改为给定的RGB值。这可以让你改变颜色1,通常是红色,紫色或蓝色或任何其他你喜欢的颜色。不幸的是,Linux控制台不支持这一点,所以我无法尝试它,也无法提供任何示例。您可以通过调用can_change_color()来检查您的终端是否可以做到这一点,如果功能存在,can_change_color()将返回True。如果您有幸拥有这样一个优秀的终端,请参考系统的手册页以获得更多信息。
用户输入
Python的curses模块添加了一个基本的文本输入小部件。
有两种方法:
- getch()刷新屏幕,然后等待用户敲一个键, 如果之前调用echo()时显示键值。您可以选择在暂停之前指定光标应该移动到的坐标。
- getkey() 执行相同的操作,但将整数转换为字符串。单个字符返回为1个字符的字符串,特殊的键(如函数键)返回包含键名(如KEY_UP或^G)的更长的字符串。
可以不等待用户输入
可以不使用nodelay()窗口方法等待用户。在nodelay(True)之后,窗口的getch()和getkey()变为非阻塞。为了表示没有准备好输入,getch()返回curses。ERR(值为-1)和getkey()引发异常。还有一个halfdelay()函数,它可以用来(实际上)为每个getch()设置一个计时器;如果在指定的延迟内没有可用的输入(以十分之一秒为单位),curses将引发异常。
getch()返回整数
getch()方法返回一个整数;如果在0到255之间,则表示按下的键的ASCII码。大于255的值是特殊键,如Page Up、Home或光标键。您可以将返回的值与常量(如curses)进行比较。KEY_PPAGE,curses。KEY_HOME或curses.KEY_LEFT。程序的主循环可能是这样的:
while True:c = stdscr.getch()if c == ord('p'):PrintDocument()elif c == ord('q'):break # Exit the while loopelif c == curses.KEY_HOME:x = y = 0
curses.ascii模块提供ascii类成员函数,这些函数接受整数或1个字符串参数;在为这样的循环编写更具可读性的测试时,这些方法可能很有用。它还提供了转换函数,该函数接受整数或1个字符字符串参数,并返回相同的类型。例如,curses .ascii.ctrl()返回与其参数对应的控制字符。
还有一个方法可以检索整个字符串getstr()。它并不经常使用,因为它的功能非常有限;惟一可用的编辑键是退格键和回车键,回车键终止字符串。它可以选择限制为固定数量的字符。
curses.echo() # Enable echoing of characters# Get a 15-character string, with the cursor on the top line
s = stdscr.getstr(0,0, 15)
cruses.textpad模块提供一个文本框,该文本框支持一组类似于emacs的键绑定。Textbox类的各种方法都支持使用输入验证进行编辑,并收集带有或不带尾随空格的编辑结果。这里有一个例
import curses
from curses.textpad import Textbox, rectangledef 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 contentsmessage = box.gather()
不懂啊
Python-Curses模块相关推荐
- python的curses模块使用
参考:http://docs.python.org/2/howto/curses.html curses(早期名称,现在是ncurses)包的封装,用于实现终端无关的控制台输出以及输入处理.curse ...
- Python Curses
部分转载自:python curses使用 pythonlab pythonlab 彩色终端 官方API 可爱的 Python:Curses 编程 简介 python 中curses封装了c语言的cu ...
- [转]python各模块的学习
[-] 01 关于本书 02 代码约定 03 关于例子 04 如何联系我们 1 核心模块 11 介绍 111 内建函数和异常 112 操作系统接口模块 113 类型支持模块 114 正则表达式 115 ...
- python 各种模块学习
from:https://blog.csdn.net/weiwangchao_/article/details/70570508 转载:.... Python的模块大全,很全,有详细介绍! 另外附Py ...
- Python Re 模块超全解读!详细
内行必看!Python Re 模块超全解读! 2019.08.08 18:59:45字数 953阅读 121 re模块下的函数 compile(pattern):创建模式对象 > import ...
- python argparse模块_Python argparse模块应用实例解析
这篇文章主要介绍了Python argparse模块应用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 简介 argparse是python ...
- 关于使用python logging模块的几点总结
关于使用python logging模块的几点总结 使用python的标准日志模块logging可以非常方便地记录日志.Python日志系统非常丰富.添加结构化或非结构化日志输出到python代码,写 ...
- python高级-模块(14)
一.python中的模块 有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt函数,必须用语句#include <math.h>引入math.h这个头文件,否则是无法正常进行调用的. ...
- 转载: Python os 模块的功能以及子函数介绍
原文链接: python之os模块 - 程序生(Codey) - 博客园 https://www.cnblogs.com/cxscode/p/8085326.html 一.Python OS模块介绍 ...
- 简单介绍python process模块
在python中大部分情况需要使用多进程,python提供了multiprocessing模块.multiprocessing模块的功能众多:支持子进程.通信和共享数据.执行不同形式的同步,提供了Pr ...
最新文章
- 2021年大数据Spark(六):环境搭建集群模式 Standalone
- 与c交互_SV DPI-C接口学习心得
- [codevs 1249]	多边形的面积
- 激活Win Server 2008 R2 Datacenter
- 廖雪峰 练习 把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字...
- oracle表被锁了怎么处理
- TiDB数据库备份恢复与数据迁移
- 8年php薪資,8年PHP求稳定远程团队带走
- 迷茫中,要让人生更精彩
- Jeesite 自定义api接口 404 访问不到页面
- [转载] 【原创】Python 3 查看字符编码方法
- 如何用Python实现杨辉三角和心
- .NET简谈观察者模式
- 【IRA/GSM/UCS2】the difference of IRA/GSM/UCS2 character set
- 生物医药数据库-生物医药全生命周期数据(网址)
- Python写一个简单的贪吃蛇程序
- 数学建模系列-预测模型(五)---马尔可夫链
- 群晖 docker 版 transmission 安装 Web UI
- 常见的几种加密方法和实现
- JavaScript 面向对象(二)——案列篇