嗨嗨!大家好!歡迎來到 Rust 三十天挑戰的番外篇第三十一天!
經過前面三十天的學習,我們一起打造了一個完整的部落格後端 API。今天我想跟大家分享一個超級酷的 Rust 函式庫 —— Ratatui!這個函式庫讓我們可以在終端裡創造出美麗、實用的使用者介面,完全顛覆你對「終端應用程式」的刻板印象。
還記得小時候看到駭客電影裡那些酷炫的終端介面嗎?或者你有用過 htop
、lazygit
這些漂亮的終端工具?沒錯,這些都是 TUI(Terminal User Interface)應用程式的典型例子!
與傳統的命令列工具相比:
ls
、grep
、curl
- 執行完就結束,輸出文字後離開htop
、lazygit
、spotify-tui
- 有完整介面,可以即時互動而 Ratatui 就是讓我們用 Rust 輕鬆打造這種酷炫 TUI 應用的神器!
讓我們從最簡單的 "Hello, Ratatui!" 開始:
use ratatui::{
backend::CrosstermBackend,
layout::Alignment,
style::{Color, Style},
widgets::{Block, Borders, Paragraph},
Terminal,
};
use std::io;
use crossterm::{event, execute};
use crossterm::event::{Event, KeyCode};
use crossterm::terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 設置終端
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
loop {
terminal.draw(|frame| {
let area = frame.area();
let block = Block::default()
.title("我的第一個 TUI 程式")
.borders(Borders::ALL)
.style(Style::default().fg(Color::Cyan));
let paragraph = Paragraph::new("按 'q' 退出!")
.block(block)
.alignment(Alignment::Center);
frame.render_widget(paragraph, area);
})?;
if event::poll(std::time::Duration::from_millis(50))? {
if let Event::Key(key) = event::read()? {
if let KeyCode::Char('q') = key.code {
break;
}
}
}
}
// 清理終端
disable_raw_mode()?;
execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
Ok(())
}
把這段程式碼存成 main.rs
,然後在 Cargo.toml
加上:
[dependencies]
ratatui = "0.30.0-alpha.5"
crossterm = "0.29.0"
執行 cargo run
,你就會看到一個漂亮的終端介面!🎉
說到 TUI 應用,我最近用 Ratatui 做了一個終端版的 Kanban 看板,讓我來跟大家分享一下這個專案!
這個 Kanban TUI 應用包含了:
hjkl
或方向鍵導航,就像在用 Vim 一樣順手一般模式:
h
/j
/k
/l
或方向鍵 - 在欄位和任務間導航n
- 建立新任務Enter
- 編輯選中的任務d
- 刪除任務m
- 進入移動模式,M
- 移到前一欄q
- 退出程式編輯模式:
Tab
或 ↓
- 下一個欄位↑
- 上一個欄位+
/=
- 提高優先級,-
- 降低優先級Enter
- 確認,Esc
- 取消開發這個專案讓我深深體會到 Ratatui 的魅力:
// App 結構體管理所有應用狀態
pub struct App {
pub board: Board,
pub selected_column: usize,
pub selected_task: usize,
pub input_mode: InputMode,
pub edit_state: Option<EditState>,
}
// UI 就是狀態的純函數
fn ui(f: &mut Frame, app: &App) {
// 根據當前狀態渲染介面
}
這種設計讓邏輯非常清晰:狀態變更 → UI 自動更新。
pub fn handle_input(app: &mut App, key: KeyEvent) -> io::Result<bool> {
match app.input_mode {
InputMode::Normal => handle_normal_mode(app, key),
InputMode::Editing => handle_editing_mode(app, key),
InputMode::AddingTask => handle_adding_mode(app, key),
InputMode::MovingTask => handle_moving_mode(app, key),
}
}
不同模式有完全不同的鍵盤綁定,這讓應用程式可以有很豐富的互動方式。
使用 SQLite 做資料存儲,讓看板狀態可以跨會話保存:
pub fn save_board(board: &Board) -> io::Result<()> {
let conn = init_database()?;
// 儲存到資料庫的邏輯
}
pub fn load_board() -> io::Result<Board> {
let conn = init_database()?;
// 從資料庫載入的邏輯
}
Ratatui 提供了超多好用的 UI 元件:
// 各種酷炫元件一應俱全
Chart::default() // 圖表!
Table::default() // 表格!
Gauge::default() // 進度條!
Tabs::default() // 分頁!
List::default() // 清單!
Sparkline::default() // 迷你圖表!
Calendar::default() // 行事曆!
use ratatui::layout::{Constraint, Direction, Layout};
let chunks = Layout::default()
.direction(Direction::Horizontal)
.constraints([
Constraint::Percentage(33),
Constraint::Percentage(33),
Constraint::Percentage(34)
])
.split(area);
一行程式碼就能做出響應式布局,自動適應任何終端大小!
use ratatui::style::{Color, Modifier, Style};
// 優先級顏色對應
let style = match task.priority {
Priority::Critical => Style::default().fg(Color::Red),
Priority::High => Style::default().fg(Color::Yellow),
Priority::Medium => Style::default().fg(Color::Blue),
Priority::Low => Style::default().fg(Color::Green),
};
開發完這個 Kanban 專案後,我發現 TUI 應用的潛力真是無窮無盡:
lazygit
那樣的視覺化 Git 操作介面Ratatui 有一個非常活躍和友善的社群:
如果你也想嘗試 TUI 開發,我的建議是:
先做個 Hello World,感受一下 Ratatui 的基本概念:
Ratatui 的範例程式碼寫得非常好,從中可以學到很多最佳實務。
做一個你自己會用的工具!我選擇做 Kanban 是因為我真的需要一個簡單的任務管理工具。
TUI 開發有它的學習曲線,特別是狀態管理和事件處理。多實驗、多嘗試,很快就會上手。
想立刻試試看嗎?這裡有個最小可用的專案模板:
Cargo.toml:
[package]
name = "ratatui-first"
version = "0.1.0"
edition = "2024"
[dependencies]
ratatui = "0.30.0-alpha.5"
crossterm = "0.29.0"
main.rs:
// 就是前面展示的 Hello World 程式碼
// 複製貼上就能跑!
執行 cargo run
,你的第一個 TUI 應用就誕生了!
三十天的 Rust 學習之旅到這裡就要告一段落了,但這絕不是結束,而是一個全新的開始!
從第一天的 "Hello, World!" 到第三十天的完整部落格後端,我們一起走過了 Rust 的基礎語法、所有權系統、錯誤處理、非同步程式設計,最後還打造了一個實用的 Web API。
今天的 Ratatui 分享,我希望能為大家開啟另一扇門:Rust 不僅僅適合做後端服務,它在終端應用開發上也同樣出色。無論是提升工作效率的工具,還是有趣的個人專案,TUI 都是一個很棒的選擇。
記住,學習程式語言最好的方式就是用它來解決實際問題。不管是部落格後端、Kanban 看板,還是任何你能想像到的應用,都可以成為你練習和成長的機會。
希望這三十一天的內容對大家有幫助。如果你也做了什麼有趣的 Rust 專案,歡迎分享出來讓大家看看!
讓我們一起繼續在 Rust 的世界裡探索和創造吧!
P.S. 我的 Kanban TUI 專案完整程式碼可以在 GitHub 上找到,歡迎大家 fork、修改,或是提供改進建議!讓我們一起把這個小工具變得更棒~
本文是「我的 Rust IT 鐵人賽三十天挑戰:大家一起跟Rust當好朋友吧!」系列的理論上的最終篇章。感謝大家的陪伴,希望有朝一日可以再次相遇!