不清屏的Python Curses
我想在Python中使用Curses库,但不想清空屏幕。原因是我希望我的应用能在现有屏幕上弹出一个简单的小菜单,然后很快退出。虽然不太理想,但如果退出时菜单的残留部分留在屏幕上也是可以接受的。这个想法是为了快速实用的系统管理应用和脚本,外观不重要。
看起来Python的初始化函数总是会清空屏幕。我记得几年前看到过一个非Python的应用做到了我想要的效果,所以我知道这至少在C语言的Curses程序中是可能的。
2 个回答
Python的curses库里有一个叫做 filter
的功能,它可以实现你想要的效果:
curses.filter()
这个filter()功能如果要用,必须在调用initscr()之前先调用它。这样做的效果是,在这两个调用之间,LINES会被设置为1;一些功能,比如清屏、光标移动等,会被禁用;而光标的起始位置会被设置为换行符的值。这样一来,光标就只能在当前这一行活动,屏幕的更新也只限于这一行。 这可以用来实现逐字符的行编辑,而不影响屏幕的其他部分。
因为程序只知道一行,所以它不会清空整个屏幕。这对于单行输入提示很有用(如果需要的话,这一行是可以被清空的)。
注意:这仍然会使用终端初始化序列,这可能会根据终端的设置在(xterm风格的)备用屏幕之间切换。
我不会说“这不可能”,但我可以说“用普通的Curses/NCurses是做不到的”。
根本的问题在于,当Curses库初始化时,它无法获取终端的当前状态,特别是现在显示的字符和图形。
在早期的PC时代,屏幕是直接和内存连接的,所以当程序运行时,它可以访问当前屏幕的状态,以便捕捉并可能在之后恢复这个状态。
但对于一般的智能终端来说,情况并不一定如此。在Linux或Mac上,终端类型是某种“xterm”。而在Windows控制台终端上,它是ANSI风格的终端(需要注意的是,xterm也是一种ANSI终端)。终端类型是Curses依赖的termcap/terminfo库使用的代码,用来知道如何移动光标、删除字符和行、设置颜色或反转视频等。
Curses与屏幕的所有交互都是通过打印ESC转义序列来完成的,而不是直接操作内存。它不使用帧缓冲区。
如果你查看一份XTerm转义序列的列表,你会发现没有任何内容可以将屏幕的内容反馈给主程序。不过,有一种替代的帧缓冲区。例如,vim
就是一个例子。当你用vim
编辑文件时,vim
会占用整个屏幕。但当你退出时,原来的屏幕会被恢复。vim
切换到了替代屏幕缓冲区,并在那儿完成所有操作,然后在退出时恢复主屏幕缓冲区。但这只是一个简单的切换过程,vim
并不知道原始屏幕缓冲区的内容,也无法访问它。
如果你使用像Linux控制台这样的东西(可以通过功能键切换屏幕),或者像GNU Screen这样的工具,这些情况就不同了。这些依赖于不同的概念(Linux控制台的设备驱动程序和GNU Screen的伪终端),而整体程序自己维护每个屏幕的状态。但我知道的,普通程序无法获取这些信息。如果有的话,那也是通过某种专有的方法,而不是Curses。