最近看到几个有意思的基于文本终端的 UI 框架,还可以制作命令行网易云音乐。
Curses
首先出场的是Curses[1]。
Curse
Curses 是一个能提供基于文本终端窗口功能的动态库,它可以:
使用整个屏幕创建和管理一个窗口使用 8 种不同的彩色为程序提供鼠标支持使用键盘上的功能键
Curses 可以在任何遵循 ANSI/POSIX 标准的 Unix/Linux 系统上运行。Windows 上也可以运行,不过需要额外安装windows-curses库:
pipinstallwindows-curses
上面图片,就是一哥们用 Curses 写的俄罗斯方块游戏[2],是不感觉满满的回忆吧,可以拿去复活古董机了。
我们也来试试牛刀:
importcursesmyscreen=curses.initscr()myscreen.border(0)myscreen.addstr(12,25,”Pythoncursesinaction!”)myscreen.refresh()myscreen.getch()curses.endwin()需要注意addstr前两个参数是字符坐标,不是像素坐标getch会阻塞程序,直到等待键盘输入curses.endwin()作用是退出窗口如果需要持续监听用户的交互,需要写个循环,并对getch()获得的输入进行判断
代码运行效果如下:
小试牛刀
Curses 非常轻巧,特别适合处理一下简单交互,代替复杂参数输入的程序,既优雅,有简单,而且 Curses 也是其他文字终端 UI 的基础。
Npyscreen
Npyscreen[3]也是一个用了编写文本终端的 Python 组件库,是基于 Curses 构建的应用框架。
比起 Curses,Npyscreen 更接近 UI 式编程,通过组件的组合完成 UI 展示和交互,而且 Npyscreen 可以自适应屏幕变化。
Npyscreen 提供了多个控件,比如 表单(Form)、单行文本输入框(TitleText)、日期控件(TitleDateCombo)、多行文本输入框(MultiLineEdit)、单选列表(TitleSelectOne)、进度条(TitleSlider)等多种控件。
提供强大的功能,满足快速开发程序的要求,无论是简单的单页程序还是复杂的多页应用。
来看一个小例子:
importnpyscreenclassTestApp(npyscreen.NPSApp):defmain(self):#Theselinescreatetheformandpopulateitwithwidgets.#Afairlycomplexscreeninonly8orsolinesofcode-alineforeachcontrol.F=npyscreen.Form(name=”WelcometoNpyscreen”,)t=F.add(npyscreen.TitleText,name=”Text:”,)fn=F.add(npyscreen.TitleFilename,name=”Filename:”)fn2=F.add(npyscreen.TitleFilenameCombo,name=”Filename2:”)dt=F.add(npyscreen.TitleDateCombo,name=”Date:”)s=F.add(npyscreen.TitleSlider,out_of=12,name=”Slider”)ml=F.add(npyscreen.MultiLineEdit,value=”””trytypinghere!\nMutilinetext,press^Rtoreformat.\n”””,max_height=5,rely=9)ms=F.add(npyscreen.TitleSelectOne,max_height=4,value=[1,],name=”PickOne”,values=[“Option1″,”Option2″,”Option3″],scroll_exit=True)ms2=F.add(npyscreen.TitleMultiSelect,max_height=-2,value=[1,],name=”PickSeveral”,values=[“Option1″,”Option2″,”Option3″],scroll_exit=True)#ThisletstheuserinteractwiththeForm.F.edit()print(ms.get_selected_objects())if__name__==”__main__”:App=TestApp()App.run()引入 Npyscreen 模块,如果没有可以通过 pip 安装:pip install npyscreen继承npyscreen.NPSApp创建一个应用类TestApp实现main方法,方法里创建一个Form表单对象,然后向表单对象上添加各种控件,并设置控件的一些属性调用表单对象的Edit方法,将操作权交给用户在运行时,实例化TestAPP,然后调用run方法启动应用,应用即可进入等待用户交互的状态
上面代码运行的效果如下:
Npyscreen[Tab] / [Shift Tab] 用于切换控件焦点[回车] / [空格] 用于进入选择、设置、确认在选择框架中,方向键与vim[4]操作类似,即通过 hjkl 来控制
是不是感觉很神奇,用文本原来可以做这么多复杂的操作,之前对命令行中的进度显示的疑惑是否有所清晰了~
Urwid
如果说 Curses 和 Npysreen 是轻量级的文本终端 UI 框架,那么Urwid[5]绝对称得上是重量级选手。
Urwid 包含了众多开发文本 UI 的特性,例如:
看看效果:
消息框
多字体
色彩
不知道你看了是什么感觉,我的感觉是:这也太卷了吧~
几乎可以做 GUI 下的所有事情!
更厉害的是,Urwid 完全是按照面向对象的思想打造的框架:
Urwid 结构图
现在我们来小试一把,感受一下 Urwid 的强大:
importurwiddefshow_or_exit(key):ifkeyin(‘q’,’Q’):raiseurwid.ExitMainLoop()txt.set_text(repr(key))txt=urwid.Text(u”HelloWorld”)fill=urwid.Filler(txt,’middle’)loop=urwid.MainLoop(fill,unhandled_input=show_or_exit)loop.run()先引入 urwid 模块定义了一个输入事件处理方法show_or_exit处理方法中,当输入按键是 q 或者 Q 时,退出主循环,否则将按键名称显示出来urwid.Text是一个文本控件,接受一个字符串作为显示信息urwid.Filler类似于 panel,将 txt 控件填充在上面,位置设置在窗口中央urwid.MainLoop设置 Urwid 的主循环,将 fill 作为控件的绘制入口,参数unhandled_input接受一个按键事件处理方法,用的就是前面定义的show_or_exitloop.run()启动 UI,并监控各种事件
运行这段代码,就可以看到命令行被设置为交互模式,按键时会在窗口中央显示出键名,如果按下 q 键,程序就会退出。
注意:Urwid 只能在 Linux 操作系统中运行,Windows 上会因为缺失必要组件无法运行
总结
限于篇幅,这里只展示了三种文本终端框架,不过已经能对基于文本终端 UI 框架的强大感受一二了。
还有一些框架也很优秀,比如 prompt_toolkit,有兴趣的同学可以研究一下。
虽然基于文本终端的 UI 早已不是主流,但是在一些特殊的行业或者业务中,还是有其存在的价值,研究一下,说不定在特殊的地方可以帮助到我们。
最后,推荐一个很有意思的基于文本终端的应用 ——命令行网易云音乐[9]:
NetEase-MusicBox
是基于 Curses 开发,如果运行起来,能被它的强悍所震撼,有空可以玩玩,比心!
加入知识星球【我们谈论数据科学】
500 小伙伴一起学习!