Python-Curses模块

Python-Curses模块Python Curses 什么是 Curses PythonCurses 模块开始我们的编程吧 WindowsandPa 什么是 Curses curses 库为基于文本的终端提供独立于终端的屏幕绘制和键盘处理设施 这些终端包括 VT100s Linux 控制台和各种程序提供的模拟终端 显示终端支持各种控制代码来执行常见的操作 如移动光标 滚动屏幕和擦除区域 不同的终端使用的代码差别很大 而且常常有

什么是Curses?

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.nocbreak() stdscr.keypad(False) curses.echo() 

反转对curses友好的终端设置。然后调用endwin()函数将终端恢复到原来的操作模式。

curses.endwin() 

在调试一个cruses应用程序时,一个常见的问题是,当应用程序死亡而没有将终端恢复到以前的状态时,您的终端就会陷入混乱。在Python中,这通常发生在代码有bug并引发未捕获异常时。例如,当您键入键时,键不再回显到屏幕,这使得使用shell变得困难。

重要使用方法(包装用法)

在Python中,您可以通过导入curses .wrapper()函数并像这样使用它来避免这些复杂性,并使调试变得更加容易:

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) 

包装器()函数接受一个可调用对象并执行上面描述的初始化,如果有颜色支持,还初始化颜色。然后运行您提供的可调用的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的一部分,现在要改变已经太迟了。

这是因为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()来更新屏幕。

显示文本

  • 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库将尝试抑制闪烁的光标,您无需担心将其放在奇怪的位置。

属性和颜色

  • 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() 

让我们把这些放在一起。要将颜色1更改为白色背景上的红色文本,您可以调用:

stdscr.addstr(0,0, "RED ALERT!", curses.color_pair(1) 

非常漂亮的终端可以将实际颜色的定义更改为给定的RGB值。这可以让你改变颜色1,通常是红色,紫色或蓝色或任何其他你喜欢的颜色。不幸的是,Linux控制台不支持这一点,所以我无法尝试它,也无法提供任何示例。您可以通过调用can_change_color()来检查您的终端是否可以做到这一点,如果功能存在,can_change_color()将返回True。如果您有幸拥有这样一个优秀的终端,请参考系统的手册页以获得更多信息。

用户输入

  • 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 loop elif 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, 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() 

不懂啊

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/205173.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午6:38
下一篇 2026年3月19日 下午6:38


相关推荐

  • openclaw小龙虾AI养成指南

    openclaw小龙虾AI养成指南

    2026年3月12日
    2
  • Mysql主从复制的搭建及原理

    Mysql主从复制的搭建及原理

    2021年5月29日
    123
  • JAVA 中级面试题 (附答案)

    JAVA 中级面试题 (附答案)问题大多取自点击打开链接 在网上找了一些答案,也添加了一些几乎是必问的题一、    基础知识:1)   HashMap,LinkedHashMap,TreeMap的区别1.        HashMap,LinkedHashMap,TreeMap都属于Map。2.        Map的主要作用是用于存储键(key)值(value)对,根据键得到值,因此不允许键重复,但允许值重复…

    2022年6月15日
    34
  • ERROR running qmake

    ERROR running qmake1>ReadingQtconfiguration(D:/SoftWare/QT5.9.3/5.9.3/msvc2017_64/bin/qmake)1>GHViewerDetect.vcxproj:error:ERRORrunningqmake1>GHViewerDetect.vcxproj:error:qmake:(D:/SoftWare/QT5.9.3/5.9.3/msvc2017_64/bin/qmake)1>GHViewerDetect.vcx

    2022年5月19日
    104
  • 字节码万岁!!!

    字节码万岁!!!后记 这篇文章的想法来源于我在看 V8JavaScript 引擎资料时的发现 V8 引擎最初是把 JavaScript 编译成了机器指令 后来发现了一些弊端 转而使用了字节码 这就激起了我的好奇心 又去看了一下别的语言 发现真是不得了 大部分的语言都采用了字节码的实现方式 Java Python Ruby PHP Perl Lua C VB NET 他们虽然语法不同 但是底层都不

    2026年3月18日
    2
  • Linux 重启oracle数据库[通俗易懂]

    Linux 重启oracle数据库[通俗易懂]Linux下重启oracle数据库步骤//1.使用oracle用户登录数据库 su–oracle//2.进入Sqlplus控制台 sqlplus/nolog//3.连接到系统管理员 connect/assysdba//4.关闭数据库 shutdownimmediate//5.启动数据库 startup//6.退出sqlplus控制台 exit//7.进入监听器控制台 lsnrctl//8.启动监听器 start//9.退出监听器控

    2022年8月31日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号