文本用户界面(TUIText-based-User-Interface)
TUI 的定义、交互方式和常见工具。
#status / growing
#type / concept
TUI(文本用户界面)
一句话定义
TUI(Text-based User Interface)是在终端中使用文本字符绘制的交互式界面,提供菜单、按钮、列表、面板等图形化元素,但全部由字符渲染,不依赖图形环境。
核心机制 / 工作原理
TUI 通过 ANSI 转义码控制终端的光标位置、颜色和文本样式,在字符网格上”画”出界面元素:
- 光标定位:
\e[10;20H将光标移动到第 10 行第 20 列。 - 颜色控制:
\e[31m设置前景红色,\e[42m设置背景绿色。 - 特殊字符:用
─│┌┐└┘画边框,用█▓▒░画进度条。 - Alternate Screen Buffer:切换到备用屏幕缓冲区,退出时恢复原终端内容。
- 输入处理:捕获键盘事件(包括方向键、鼠标点击),而非逐行读取 stdin。
TUI vs CLI vs GUI
| 维度 | CLI | TUI | GUI |
|---|---|---|---|
| 交互模式 | 输入命令 -> 输出结果 | 持续交互、实时刷新 | 鼠标点击、窗口拖拽 |
| 视觉呈现 | 纯文本输出 | 字符绘制的界面元素 | 像素渲染的窗口 |
| 脚本化 | 容易(管道、重定向) | 困难(需要屏幕) | 困难 |
| 资源消耗 | 最低 | 低 | 高 |
| 典型场景 | 自动化脚本、快速操作 | 交互式管理工具 | 日常桌面应用 |
主流 TUI 框架
跨语言
| 框架 | 语言 | 特点 |
|---|---|---|
| ncurses | C | 最老牌,几乎所有 TUI 的底层 |
| blessed / blessed-contrib | Node.js | Web 开发者友好,Widget 丰富 |
| tui-rs / ratatui | Rust | 现代设计,性能优异(ratatui 是 tui-rs 的社区 fork) |
| bubbletea | Go | Elm 架构,组合式设计 |
| textual | Python | 类 CSS 样式系统,支持鼠标 |
| tview | Go | 轻量级,开箱即用 |
常见 TUI 应用
- htop / btop:进程监控和管理
- ranger / lf:文件管理器
- lazygit:Git 操作界面
- k9s:Kubernetes 集群管理
- vim / neovim:文本编辑器
- ncdu:磁盘使用分析
- nmtui:NetworkManager 的 TUI 界面
- yazi:新一代文件管理器(Rust)
最小例子
一个用 Python textual 库写的最简 TUI:
from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, Static
class HelloApp(App):
def compose(self) -> ComposeResult:
yield Header()
yield Static("Hello, TUI!")
yield Footer()
if __name__ == "__main__":
HelloApp().run()
运行后在终端中显示一个带标题栏、文本和底部快捷键提示的界面。
TUI 的现代复兴
近年来 TUI 工具经历了一波复兴,原因包括:
- SSH 远程管理:服务器没有 GUI,TUI 是最佳交互方式。
- 开发者体验:TUI 工具比 Web UI 更快、更专注(如 lazygit vs GitHub Desktop)。
- Rust/Go 生态:新语言降低了 TUI 开发门槛(ratatui、bubbletea)。
- 终端模拟器进步:Kitty、Alacritty、WezTerm 支持真彩色、图片显示、GPU 加速。
- 极客美学:r/unixporn 等社区推动了终端美化的文化。
边界与常见误解
- TUI 不是”过时的技术”,而是在特定场景下比 GUI 更高效的方案。
- TUI 不等于”简陋”,现代 TUI 工具(如 lazygit)的交互设计可以非常精致。
- TUI 不能完全替代 GUI:涉及图片预览、富媒体编辑等场景仍然需要图形环境。
- 终端中的图片显示(如 yazi 预览图片)依赖终端模拟器的协议支持(Sixel/iTerm2/Kitty Protocol),不是所有终端都支持。