Python文本终端GUI框架详解
今天笔者带大家,梳理几个常见的基于文本终端的 UI 框架,一睹为快!
Curses
首先出场的是 Curses。
Curses 是一个能提供基于文本终端窗口功能的动态库,它可以:
-
使用整个屏幕
-
创建和管理一个窗口
-
使用 8 种不同的彩色
-
为程序提供鼠标支持
-
使用键盘上的功能键
Curses 可以在任何遵循 ANSI/POSIX 标准的 Unix/Linux 系统上运行。Windows 上也可以运行,不过需要额外安装 windows-curses 库:
pip install windows-curses
上面图片,就是一哥们用 Curses 写的 俄罗斯方块游戏,是不感觉满满的回忆吧,可以拿去复活古董机了。
我们也来试试牛刀:
import cursesmyscreen = curses.initscr()myscreen.border(0)
myscreen.addstr(12, 25, "Python curses in action!")
myscreen.refresh()
myscreen.getch()curses.endwin()
-
需要注意 addstr 前两个参数是字符坐标,不是像素坐标
-
getch 会阻塞程序,直到等待键盘输入
-
curses.endwin() 作用是退出窗口
-
如果需要持续监听用户的交互,需要写个循环,并对 getch() 获得的输入进行判断
代码运行效果如下:
Curses 非常轻巧,特别适合处理一下简单交互,代替复杂参数输入的程序,既优雅,有简单,而且 Curses 也是其他文字终端 UI 的基础。Npyscreen
Npyscreen
也是一个用了编写文本终端的 Python 组件库,是基于 Curses 构建的应用框架。
比起 Curses,Npyscreen 更接近 UI 式编程,通过组件的组合完成 UI 展示和交互,而且 Npyscreen 可以自适应屏幕变化。
Npyscreen 提供了多个控件,比如 表单(Form)、单行文本输入框(TitleText)、日期控件(TitleDateCombo)、多行文本输入框(MultiLineEdit)、单选列表(TitleSelectOne)、进度条(TitleSlider)等多种控件。
提供强大的功能,满足快速开发程序的要求,无论是简单的单页程序还是复杂的多页应用。
来看一个小例子:
import npyscreenclass TestApp(npyscreen.NPSApp):def main(self):# These lines create the form and populate it with widgets.# A fairly complex screen in only 8 or so lines of code - a line for each control.F = npyscreen.Form(name = "Welcome to Npyscreen",)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 = """try typing here!\nMutiline text, press ^R to reformat.\n""",max_height=5, rely=9)ms = F.add(npyscreen.TitleSelectOne, max_height=4, value = [1,], name="Pick One",values = ["Option1","Option2","Option3"], scroll_exit=True)ms2= F.add(npyscreen.TitleMultiSelect, max_height =-2, value = [1,], name="Pick Several",values = ["Option1","Option2","Option3"], scroll_exit=True)# This lets the user interact with the Form.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 方法启动应用,应用即可进入等待用户交互的状态
上面代码运行的效果如下:
-
[Tab] / [Shift + Tab] 用于切换控件焦点
-
[回车] / [空格] 用于进入选择、设置、确认
-
在选择框架中,方向键与 vim[4] 操作类似,即通过 hjkl 来控制
是不是感觉很神奇,用文本原来可以做这么多复杂的操作,之前对命令行中的进度显示的疑惑是否有所清晰了 ~
Urwid
如果说 Curses 和 Npysreen 是轻量级的文本终端 UI 框架,那么 Urwid 绝对称得上是重量级选手。
Urwid 包含了众多开发文本 UI 的特性,例如:
-
应用窗口自适应
-
文本自动对齐
-
轻松设置文本块
-
强大的选择框控件
-
可以和各种基于事件驱动的框架集成,比如和 Twisted, Glib, Tornado等等
-
提供诸如编辑框、按钮、多(单)选框 等多种预制控件
-
显示模式支持原生、Curses模式、LCD 显示屏 以及 网络显示器
-
支持 UTF-8 以及 CJK 字符集(可以显示中文)
-
支持多种颜色
看看效果:
不知道你看了是什么感觉,我的感觉是:这也太卷了吧~几乎可以做 GUI 下的所有事情!更厉害的是,Urwid 完全是按照面向对象的思想打造的框架:
现在我们来小试一把,感受一下 Urwid 的强大:
import urwiddef show_or_exit(key):if key in ('q', 'Q'):raise urwid.ExitMainLoop()txt.set_text(repr(key))txt = urwid.Text(u"Hello World")
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_exit
-
loop.run() 启动 UI,并监控各种事件
运行这段代码,就可以看到命令行被设置为交互模式,按键时会在窗口中央显示出键名,如果按下 q 键,程序就会退出。
注意:Urwid 只能在 Linux 操作系统中运行,Windows 上会因为缺失必要组件无法运行
总结
限于篇幅,这里只展示了三种文本终端框架,不过已经能对基于文本终端 UI 框架的强大感受一二了。
还有一些框架也很优秀,比如 prompt_toolkit,有兴趣的同学可以研究一下。
虽然基于文本终端的 UI 早已不是主流,但是在一些特殊的行业或者业务中,还是有其存在的价值,研究一下,说不定在特殊的地方可以帮助到我们。
---END---
相关文章:

Python文本终端GUI框架详解
今天笔者带大家,梳理几个常见的基于文本终端的 UI 框架,一睹为快! Curses 首先出场的是 Curses。 Curses 是一个能提供基于文本终端窗口功能的动态库,它可以: 使用整个屏幕 创建和管理一个窗口 使用 8 种不同的彩色 为程序提供…...

01_lwip_raw_udp_test
1.打开UDP的调试功能 (1)设置宏定义 (2)打开UDP的调试功能 (3)修改内容,串口助手打印的日志信息自动换行 2.电脑端连接 UDP发送一帧数据 3.电路板上发送一帧数据...

学习ts(十一)本地存储与发布订阅模式
localStorage实现过期时间 目录 准备 安装 npm i rollup typescript rollup-plugin-typescript2// tsconfig.json"module": "ESNext","moduleResolution": "node", "strict": false, // rollup.config.js import …...

MySQL对NULL值处理
在使用数据库时,有时需要表示未知值,这时可以使用NULL值表示。引入NULL值后,会对原有的使用产生影响,这里记录下常见的场景,以做记录。 NULL含义 在MySQL中,NULL值表示一个未知值,表示不可知、…...

Vector 动态数组(迭代器)
C数据结构与算法 目录 本文前驱课程 1 C自学精简教程 目录(必读) 2 Vector<T> 动态数组(模板语法) 本文目标 1 熟悉迭代器设计模式; 2 实现数组的迭代器; 3 基于迭代器的容器遍历; 迭代器语法介绍 对迭…...

多组背包恰好装满方案数
链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 现在有一个大小n*1的收纳盒,我们手里有无数个大小为1*1和2*1的小方块,我们需要用这些方块填满收纳盒,请问我们有多少种不同的方法填满这个收纳盒 分析&…...

Oracle查询语句中做日期加减运算
在Oracle中,可以使用日期函数来实现日期的加减。 若想在日期上加上一定的天数,可以使用"INTERVAL"关键字。例如,如果要将一个日期加上3天,可以使用以下代码: SELECT SYSDATE INTERVAL 3 DAY FROM DUAL; …...

Unity贝塞尔曲线的落地应用-驱动飞行特效
前言 本文教你怎么用贝塞尔曲线驱动一个飞行特效 中间点的准备 开放一些可以给策划配置的变量 startPos flyEffect.transform.position; var right (GetAimPoistion(targetActor) - flyEffect.transform.position).x > 0?1:-1; midPos startPos new Vector3(righ…...

VTK——设置交互样式上的鼠标回调函数
函数介绍 VTKPointPickerInteractorStyle是一个自定义的交互样式类,它是VTK库中vtkInteractorStyleTrackballCamera类的子类。VTK(Visualization Toolkit)是一个开源的,跨平台的库,用于处理、渲染和视觉化科学数据。它…...

Flutter实现动画列表AnimateListView
由于业务需要,在打开列表时,列表项需要一个从右边飞入的动画效果,故封装一个专门可以执行动画的列表组件,可以自定义自己的动画,内置有水平滑动,缩放等简单动画。花里胡哨的动画效果由你自己来定制吧。 功…...

【LeetCode-中等题】236. 二叉树的最近公共祖先
文章目录 题目方法一:后序遍历 回溯 题目 方法一:后序遍历 回溯 解题的核心就是:采用后序遍历 讨论p,q是否在当前的root的两边,如在两边则返回当前节点root 如何不在两边,只要出现一个节点等于p或者q就…...

如何拼接两个视频在一起?
如何拼接两个视频在一起?在度过一个美好周末的时候,我和朋友一起拍摄了两组视频,准备将两个视频合并成一个并发布到朋友圈。这个想法非常棒,但是我在第一步就遇到了麻烦:如何将这两个视频拼接在一起?这听起…...

Programming abstractions in C阅读笔记:p130-p131
《Programming Abstractions In C》学习第52天,p130-p131,总结如下: 一、技术总结 1. pig latin game 通过pig latin game掌握字符复制,指针遍历等操作。 /** 输入:字符串,这里采用书中坐着自定义的get…...

如何在Windows本地快速搭建SFTP文件服务器,并通过端口映射实现公网远程访问
文章目录 1. 搭建SFTP服务器1.1 下载 freesshd服务器软件1.3 启动SFTP服务1.4 添加用户1.5 保存所有配置 2 安装SFTP客户端FileZilla测试2.1 配置一个本地SFTP站点2.2 内网连接测试成功 3 使用cpolar内网穿透3.1 创建SFTP隧道3.2 查看在线隧道列表 4. 使用SFTP客户端࿰…...

C#---第二十:不同类型方法的执行顺序(new / virtual / common / override)
本文介绍不同类型的方法,在代码中的执行顺序问题: 构造方法普通方法(暂用common代替)、虚方法(Virtual修饰)、New方法(new修饰)三个优先级相同overide方法(会替换virtual…...

lnmp架构-PHP
08 PHP源码编译 09 php初始化配置 nginx 的并发能力强 phpinfo函数 就是 显示php信息 10 php的功能模块 编译memcache模块 php的动态模块方式 mamcache 就是内存 直接从内存中命中 所以性能非常好 但是 这还不是最好的方式 工作流程 关键看后端的 php 什么时候处理完 mamcac…...

【javascript实操记录】
功能描述: 1. 利用split()方法对测试数据进行解析:学科,日期 2. 将测试数据封装成对象数组的格式 3. 使用数组的sort()方法和Date对象,将测试数据按照日期从早到晚进行排序 4. 表格数据的静态填充 5. 距离最近考试的倒计时天…...

Mysql--技术文档--悲观锁、乐观锁-《控制并发机制简单认知、深度理解》
阿丹: 首先在谈到并发控制机制的时候,我们通常会提及两种重要的锁策略。悲观锁(Pessimistic Locking)和乐观锁(Optimistic Locking)。这两个是在处理并发的时候采取的不同思路。 悲观锁: 悲观锁…...

【GO】LGTM_Grafana_Tempo(2)_官方用例改后实操
最近在尝试用 LGTM 来实现 Go 微服务的可观测性,就顺便整理一下文档。 Tempo 会分为 4 篇文章: Tempo 的架构官网测试实操跑通gin 框架发送 trace 数据到 tempogo-zero 微服务框架使用发送数据到 tempo 根据官方文档实操跑起来 tempo,中间根…...

git 口令
把当前目录变成 Git 可以管理的仓库: git init 下载一个项目和它的整个代码历史 git clone [url] 切换到 develop 分支: git checkout develop 建立并切换到 new 分支 git checkout -b new 查看所有分支: git branch -a 删除 tese …...

【回眸】剑指offer(二)解题思路
题解 | #数字在升序数组中出现的次数# JZ3数字在升序数组中出现的次数 描述 给定一个长度为 n 的非降序数组和一个非负数整数 k ,要求统计 k 在数组中出现的次数 数据范围:0≤n≤1000,0≤k≤100,数组中每个元素的值满足 0≤val≤100 要求…...

Python 基本文件操作及os库
内置函数文件操作 python内置函数提供了简单的文件操作支持。 open() open()函数打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写。 语法为: open(file,moder,buffering-1,encodingNone,errorsNone,newlineNone,closefdT…...

YOLOv5算法改进(9)— 替换主干网络之ShuffleNetV2
前言:Hello大家好,我是小哥谈。ShuffleNetV2 是一种轻量级的神经网络架构,适用于移动设备和嵌入式设备等资源受限的场景,旨在在计算资源有限的设备上提供高效的计算和推理能力,它通过引入通道重排操作和逐点组卷积来减…...

三、mycat分库分表
第五章 分库分表 一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业 务将表进行分类,分布到不同 的数据库上面,这样也就将数据或者说压力分担到不同 的库上面,如下图: 系统被切分成了&…...

gitlab提交项目Log in with Access Token错误
目录 报错信息 问题描述 解决方案 报错信息 问题描述 在提交项目到gitlab时,需要添加账户信息 ,但是报了这样一个错,原因应该就是路径问题,我在填写server地址的时候,就出现了路径问题,我把多余的几个/…...

openGauss学习笔记-56 openGauss 高级特性-DCF
文章目录 openGauss学习笔记-56 openGauss 高级特性-DCF56.1 架构介绍56.2 功能介绍56.3 使用示例 openGauss学习笔记-56 openGauss 高级特性-DCF DCF全称是Distributed Consensus Framework,即分布式一致性共识框架。DCF实现了Paxos、Raft等解决分布式一致性问题典…...

Xcode 14 pod init报错
文章目录 1.报错2.解决方法(本人亲测有效) 1.报错 [!] Oh no, an error occurred. Search for existing GitHub issues similar to yours: https://github.com/CocoaPods/CocoaPods/search?q%5BXcodeproj%5DUnknownobjectversion%2856%29.&typeIs…...

飞腾PSPA可信启动--2 数字签名证书
今天继续第二章,数字签名证书的介绍。 此章节录制了讲解视频,可以在B站进行观看:...

微前端:重塑大型项目的前沿技术
引言 随着互联网技术的飞速发展,前端开发已经从简单的页面制作逐渐转变为复杂的应用开发。在这个过程中,传统的前端开发模式已经难以满足大型项目的需求。微前端作为一种新的前端架构模式,应运而生,它旨在解决大型项目中的前端开…...

官方推荐使用的OkHttp4网络请求库全面解析(Android篇)
作者:cofbro 前言 现在谈起网络请求,大家肯定下意识想到的就是 okhttp 或者 retrofit 这样的三方请求库。诚然,现在有越来越多的三方库帮助着我们快速开发,但是对于现在的程序员来说,我们不仅要学会如何去用ÿ…...