1 个不稳定版本
0.19.0 | 2023年2月25日 |
---|
#870 在 命令行界面
在 2 crates 中使用
400KB
12K SLoC
这是一个分支,请使用官方仓库
lib.rs
:
tui 是一个用于构建丰富终端用户界面和仪表板的库。
入门
将 tui
添加为依赖项
[dependencies]
tui = "0.19"
crossterm = "0.25"
默认情况下,该crate使用 crossterm
后端,该后端在大多数平台上运行。但如果你例如想使用 termion
后端,可以通过更改你的依赖项规范来实现
[dependencies]
termion = "1.5"
tui = { version = "0.19", default-features = false, features = ['termion'] }
相同的逻辑适用于所有其他可用的后端。
创建一个 Terminal
使用 tui
的每个应用程序都应该通过实例化一个 Terminal
开始。它是一个轻量级的后端抽象,提供了诸如清屏、隐藏光标等基本功能。
use std::io;
use tui::{backend::CrosstermBackend, Terminal};
fn main() -> Result<(), io::Error> {
let stdout = io::stdout();
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
Ok(())
}
如果你之前选择了 termion
作为后端,终端可以以类似的方式创建
use std::io;
use tui::{backend::TermionBackend, Terminal};
use termion::raw::IntoRawMode;
fn main() -> Result<(), io::Error> {
let stdout = io::stdout().into_raw_mode()?;
let backend = TermionBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
Ok(())
}
你也可以参考示例来了解如何为每个可用的后端创建一个 Terminal
。
构建用户界面 (UI)
你的界面中的每个组件都将实现 Widget
特性。该库提供了一系列预定义的组件,可以满足大多数用例。你也可以自由实现自己的。
每个组件都遵循一个 builder 模式 API,提供默认配置以及自定义它们的函数。然后使用 Frame::render_widget
将组件渲染到指定的区域。
以下示例渲染了一个与终端大小相同的块
use std::{io, thread, time::Duration};
use tui::{
backend::CrosstermBackend,
widgets::{Widget, Block, Borders},
layout::{Layout, Constraint, Direction},
Terminal
};
use crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
fn main() -> Result<(), io::Error> {
// setup terminal
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
terminal.draw(|f| {
let size = f.size();
let block = Block::default()
.title("Block")
.borders(Borders::ALL);
f.render_widget(block, size);
})?;
thread::sleep(Duration::from_millis(5000));
// restore terminal
disable_raw_mode()?;
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
)?;
terminal.show_cursor()?;
Ok(())
}
布局
该库提供了一个基本但有用的布局管理对象,称为 Layout
。正如你下面和示例中看到的,该库大量使用 builder 模式来提供完全自定义。而且 Layout
也不例外。
use tui::{
backend::Backend,
layout::{Constraint, Direction, Layout},
widgets::{Block, Borders},
Frame,
};
fn ui<B: Backend>(f: &mut Frame<B>) {
let chunks = Layout::default()
.direction(Direction::Vertical)
.margin(1)
.constraints(
[
Constraint::Percentage(10),
Constraint::Percentage(80),
Constraint::Percentage(10)
].as_ref()
)
.split(f.size());
let block = Block::default()
.title("Block")
.borders(Borders::ALL);
f.render_widget(block, chunks[0]);
let block = Block::default()
.title("Block 2")
.borders(Borders::ALL);
f.render_widget(block, chunks[1]);
}
这允许您通过嵌套布局来描述响应式终端UI。请注意,默认情况下,计算出的布局会尝试完全填充可用空间。因此,如果您可能在某处需要空白空间,请尝试传递额外的约束,并不要使用相应的区域。
依赖项
~2–11MB
~97K SLoC