65 个版本 (9 个破坏性更新)

0.28.1-alpha.2 2024年8月24日
0.28.0-alpha.02024年7月27日
0.27.0-alpha.32024年3月30日
0.25.0 2023年12月18日
0.20.1 2023年3月22日

#1 in 命令行界面

Download history 60760/week @ 2024-05-04 69303/week @ 2024-05-11 78917/week @ 2024-05-18 62183/week @ 2024-05-25 61886/week @ 2024-06-01 68904/week @ 2024-06-08 71839/week @ 2024-06-15 74030/week @ 2024-06-22 72207/week @ 2024-06-29 67687/week @ 2024-07-06 66742/week @ 2024-07-13 69504/week @ 2024-07-20 72415/week @ 2024-07-27 73880/week @ 2024-08-03 77713/week @ 2024-08-10 65597/week @ 2024-08-17

300,589 每月下载量
用于 627 个 crates (573 直接使用)

MIT 许可证

1.5MB
29K SLoC

目录

Demo

Ratatui

Ratatui 是一个用于在 Rust 中创建终端用户界面的 crate。它是一个轻量级的库,提供了一套小部件和实用工具来构建复杂的 Rust TUI。Ratatui 于 2023 年从 tui-rs crate 分支出来,以继续其开发。

安装

在您的 cargo.toml 中添加 ratatui 依赖项

cargo add ratatui

Ratatui 默认使用 Crossterm,因为它在大多数平台上都有效。有关如何使用其他后端(Termion / Termwiz)的详细信息,请参阅 安装 部分 Ratatui 网站

简介

Ratatui 基于“即时渲染”和中间缓冲区的原理。这意味着对于每一帧,您的应用程序必须渲染所有应该成为 UI 部分的控件。这与保留模式渲染风格形成对比,在保留模式中,控件更新后将在下一帧自动重绘。有关更多信息,请参阅 渲染 部分,以及 Ratatui 网站

您还可以观看 FOSDEM 2024 演讲,该演讲简要介绍了终端用户界面,并展示了 Ratatui 的功能,包括一个“Hello World”演示。

其他文档

快速入门

以下示例演示了设置终端并渲染 "Hello World!" 所需的最小代码量。包含更多详细信息的完整代码位于 示例 目录中。有关不同应用程序结构方式的更多指导,请参阅 应用程序模式Hello World 教程 部分,以及 Ratatui 网站 上的各种 示例。在 模板 存储库中也有几个可用的起始模板。

使用 ratatui 构建的应用程序需要实现以下步骤

  • 初始化终端
  • 主循环以
    • 处理输入事件
    • 绘制 UI
  • 恢复终端状态

该库包含一个 prelude 模块,该模块重新导出最常见的特性和类型,以便于使用。文档中的大多数示例都会使用它而不是显示每个类型的完整路径。

初始化和恢复终端

Terminal 类型是任何 Ratatui 应用程序的主要入口点。它是对一组 Backend 实现的轻量级抽象,提供了绘制每一帧、清屏、隐藏光标等功能。它参数化于任何实现了 Backend 特性的类型,该特性有针对 CrosstermTermionTermwiz 的实现。

大多数应用程序应该在启动时进入交替屏幕,在退出时离开,并启用原始模式以禁用行缓冲和启用读取键事件。有关更多信息,请参阅 backend 模块后端 部分,以及 Ratatui 网站

绘制UI

绘图逻辑委托给一个闭包,该闭包接收一个 Frame 实例作为参数。该 Frame 提供了绘制区域的尺寸,并允许应用程序使用提供的 render_widget 方法渲染任何 Widget。在闭包返回后,执行差异比较,并将更改绘制到终端中。有关更多信息,请参阅 Widgets 部分 Ratatui 网站

处理事件

Ratatui 不包含任何输入处理。相反,可以通过直接调用后端库方法来实现事件处理。有关更多信息,请参阅 Handling Events 部分 Ratatui 网站。例如,如果您使用 Crossterm,您可以使用 crossterm::event 模块来处理事件。

示例

use std::io::{self, stdout};

use ratatui::{
    backend::CrosstermBackend,
    crossterm::{
        event::{self, Event, KeyCode},
        terminal::{
            disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
        },
        ExecutableCommand,
    },
    widgets::{Block, Paragraph},
    Frame, Terminal,
};

fn main() -> io::Result<()> {
    enable_raw_mode()?;
    stdout().execute(EnterAlternateScreen)?;
    let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;

    let mut should_quit = false;
    while !should_quit {
        terminal.draw(ui)?;
        should_quit = handle_events()?;
    }

    disable_raw_mode()?;
    stdout().execute(LeaveAlternateScreen)?;
    Ok(())
}

fn handle_events() -> io::Result<bool> {
    if event::poll(std::time::Duration::from_millis(50))? {
        if let Event::Key(key) = event::read()? {
            if key.kind == event::KeyEventKind::Press && key.code == KeyCode::Char('q') {
                return Ok(true);
            }
        }
    }
    Ok(false)
}

fn ui(frame: &mut Frame) {
    frame.render_widget(
        Paragraph::new("Hello World!").block(Block::bordered().title("Greeting")),
        frame.size(),
    );
}

运行此示例将生成以下输出

docsrs-hello

布局

该库包含一个基本但有用的布局管理对象,称为 Layout,它允许您将可用空间分割成多个区域,然后在每个区域中渲染小部件。这使您可以通过嵌套布局来描述响应式的终端UI。有关更多信息,请参阅 Layout 部分 Ratatui 网站

use ratatui::{
    layout::{Constraint, Layout},
    widgets::Block,
    Frame,
};

fn ui(frame: &mut Frame) {
    let [title_area, main_area, status_area] = Layout::vertical([
        Constraint::Length(1),
        Constraint::Min(0),
        Constraint::Length(1),
    ])
    .areas(frame.size());
    let [left_area, right_area] =
        Layout::horizontal([Constraint::Percentage(50), Constraint::Percentage(50)])
            .areas(main_area);

    frame.render_widget(Block::bordered().title("Title Bar"), title_area);
    frame.render_widget(Block::bordered().title("Status Bar"), status_area);
    frame.render_widget(Block::bordered().title("Left"), left_area);
    frame.render_widget(Block::bordered().title("Right"), right_area);
}

运行此示例将生成以下输出

docsrs-layout

文本和样式

TextLineSpan 类型是库的构建块,并用于许多地方。《Text》 是《Line》的列表,而《Line》是《Span》的列表。《Span》是一个带有特定样式的字符串。

《style》模块提供了表示各种样式选项的类型。《Style》是最重要的一个,它表示《Span》的前景色、背景色和文本属性。《style》模块还提供了一个《Stylize》特质,允许对小部件和文本使用简写语法来应用样式。有关更多信息,请参阅 Styling Text 部分 Ratatui 网站

use ratatui::{
    layout::{Constraint, Layout},
    style::{Color, Modifier, Style, Stylize},
    text::{Line, Span},
    widgets::{Block, Paragraph},
    Frame,
};

fn ui(frame: &mut Frame) {
    let areas = Layout::vertical([Constraint::Length(1); 4]).split(frame.size());

    let line = Line::from(vec![
        Span::raw("Hello "),
        Span::styled(
            "World",
            Style::new()
                .fg(Color::Green)
                .bg(Color::White)
                .add_modifier(Modifier::BOLD),
        ),
        "!".red().on_light_yellow().italic(),
    ]);
    frame.render_widget(line, areas[0]);

    // using the short-hand syntax and implicit conversions
    let paragraph = Paragraph::new("Hello World!".red().on_white().bold());
    frame.render_widget(paragraph, areas[1]);

    // style the whole widget instead of just the text
    let paragraph = Paragraph::new("Hello World!").style(Style::new().red().on_white());
    frame.render_widget(paragraph, areas[2]);

    // use the simpler short-hand syntax
    let paragraph = Paragraph::new("Hello World!").blue().on_yellow();
    frame.render_widget(paragraph, areas[3]);
}

运行此示例将生成以下输出

docsrs-styling

此分支的状态

针对原始维护者 Florian Dehau 关于 tui-rs 未来 的问题,社区中的一些成员对该项目进行了分叉,并创建了此软件包。我们期待继续Florian开始的工作 🚀

为了组织自己,我们目前使用一个 Discord 服务器,欢迎加入并聊天!还有一个 Matrix 通道,地址为 #ratatui:matrix.org

尽管我们确实使用 Discord 进行协调,但贡献并不依赖于它。我们最近推出了 Ratatui 论坛,我们的主要开源工作流程围绕 GitHub 展开。对于错误和功能,我们依赖于 GitHub。请 报告错误请求功能创建拉取请求

请确保您阅读了更新的 贡献指南,尤其是如果您对在先前存储库中打开的 PR 或问题感兴趣。

小部件

内置

该库包含以下 小部件

每个小部件都有一个相关的示例,可以在 示例 文件夹中找到。使用 cargo 运行每个示例(例如,要运行仪表盘示例 cargo run --example gauge),然后按 q 退出。

您还可以运行所有示例,通过运行 cargo make run-examples(需要 cargo-make,可以使用 cargo install cargo-make 安装)。

第三方库、引导模板和小部件

  • ansi-to-tui — 将 ansi 彩色文本转换为 ratatui::text::Text
  • color-to-tui — 解析十六进制颜色到 ratatui::style::Color
  • templates — 使用 Ratatui 和 crossterm 启动 Rust TUI 应用程序的入门模板
  • tui-builder — 包含所有功能的 MVC 框架,用于 Tui-rs + Crossterm 应用程序
  • tui-clap — 将 clap-rs 与 Tui-rs 结合使用
  • tui-log — 如何使用 Tui-rs 进行日志记录的示例
  • tui-logger — 用于 Tui-rs 的日志记录器和 Widget
  • tui-realm — 使用 React/Elm 启发式方法构建具有状态的应用程序的 Tui-rs 框架
  • tui-realm-treeview — Tui-realm 的 Treeview 组件
  • tui-rs-tree-widgets — 树数据结构的 Widget
  • tui-windows — 处理多个窗口及其渲染的 Tui-rs 抽象
  • tui-textarea — 简单而强大的多行文本编辑器 Widget,支持多个快捷键、撤销/重做、文本搜索等
  • tui-input — 支持 multiple backends 和 tui-rs 的 TUI 输入库
  • tui-term — 一个伪终端 Widget 库,可以将终端应用程序作为 ratatui Widget 渲染

应用程序

查看 awesome-ratatui,获取使用 ratatui 构建的优秀应用/库的精选列表!

替代方案

您可能还想查看 Cursive,这是构建 Rust 中文本用户界面的替代方案。

致谢

特别感谢 Pavel Fomchenkov 为 ratatui 项目和组织设计了一个 出色的标志

许可证

MIT

依赖项

~6–19MB
~283K SLoC