日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
高手過(guò)招不用鼠標(biāo),一款超好用的跨平臺(tái)命令行界面庫(kù)

而最趁手的莫過(guò)于自己親手打造的!本期 《講解開源項(xiàng)目》 就介紹一個(gè)讓你快速擁有完美命令行界面的跨平臺(tái)庫(kù)—— tui.rs。

創(chuàng)新互聯(lián)公司-成都網(wǎng)站建設(shè)公司,專注做網(wǎng)站、成都網(wǎng)站建設(shè)、網(wǎng)站營(yíng)銷推廣,申請(qǐng)域名,雅安服務(wù)器托管,網(wǎng)站運(yùn)營(yíng)有關(guān)企業(yè)網(wǎng)站制作方案、改版、費(fèi)用等問(wèn)題,請(qǐng)聯(lián)系創(chuàng)新互聯(lián)公司。

項(xiàng)目地址:https://github.com/fdehau/tui-rs

官方文檔:https://docs.rs/tui/latest/tui/index.html

你一定有過(guò)這樣的糾結(jié):我的程序需要一個(gè)界面,但使用諸如 Qt 等框架又比較繁瑣?,F(xiàn)在 tui.rs 來(lái)了,它是 Rust 下的命令行 UI 庫(kù),不僅上手方便內(nèi)置多種組件,而且效果炫酷支持跨平臺(tái)使用。

輕松實(shí)現(xiàn)一份代碼可以無(wú)縫運(yùn)行在 Linux/Windows/Mac 之上!

接下來(lái)你不僅可以快速上手 tui.rs,還會(huì)收獲多款基于它構(gòu)建的神兵利器!

一、安裝

tui.rs 采用 Rust 語(yǔ)言編寫,和所有其他 Rust 依賴的安裝方法一樣,直接在 cargo.toml 中添加依賴即可:

[dependencies]
tui = "0.17"
crossterm = "0.22"

如果需要官方示例,則直接 clone 官方倉(cāng)庫(kù):

$ git clone http://github.com/fdehau/tui-rs.git
$ cd tui-rs
$ cargo run --example demo

二、快速入門

2.1 一覽芳容

我們主要使用 tui.rs 提供的以下模塊進(jìn)行 UI 編寫(所有 UI 元素都實(shí)現(xiàn)了 Widget 或 StatefuWidget Trait):

  • bakend 用于生成管理命令行的后端
  • layout 用于管理 UI 組件的布局
  • style 用于為 UI 添加樣式
  • symbols 描述繪制散點(diǎn)圖時(shí)所用點(diǎn)的樣式
  • text 用于描述帶樣式的文本
  • widgets 包含預(yù)定義的 UI 組件

如下代碼就可以實(shí)現(xiàn)一個(gè)很簡(jiǎn)單的 tui 界面:

use crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use std::{io, time::Duration};
use tui::{
backend::{Backend, CrosstermBackend},
layout::{Alignment, Constraint, Direction, Layout},
style::{Color, Modifier, Style},
text::{Span, Spans, Text},
widgets::{Block, Borders, Paragraph, Widget},
Frame, Terminal,
};

struct App {
url: String, // 存放一些數(shù)據(jù)或者 UI 狀態(tài)
}
fn main() -> Result<(), io::Error> {
// 初始化終端
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
let mut app = App {
url: String::from(r"https://hellogithub.com/"),
};
// 渲染界面
run_app(&mut terminal, app)?;
// 恢復(fù)終端
disable_raw_mode()?;
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
)?;
terminal.show_cursor()?;

Ok(())
}

fn run_app(terminal: &mut Terminal, mut app: App) -> io::Result<()> {
loop {
terminal.draw(|f| ui(f, &mut app))?;
// 處理按鍵事件
if crossterm::event::poll(Duration::from_secs(1))? {
if let Event::Key(key) = event::read()? {
match key.code {
KeyCode::Char(ch) => {
if 'q' == ch {
break;
}
}
_ => {}
}
}
}
// 處理其他邏輯
}
Ok(())
}
fn ui(f: &mut Frame, app: &mut App) {
//
let chunks = Layout::default() // 首先獲取默認(rèn)構(gòu)造
.constraints([Constraint::Length(3), Constraint::Min(3)].as_ref()) // 按照 3 行 和 最小 3 行的規(guī)則分割區(qū)域
.direction(Direction::Vertical) // 垂直分割
.split(f.size()); // 分割整塊 Terminal 區(qū)域
let paragraph = Paragraph::new(Span::styled(
app.url.as_str(),
Style::default().add_modifier(Modifier::BOLD),
))
.block(Block::default().borders(Borders::ALL).title("HelloGitHub"))
.alignment(tui::layout::Alignment::Left);
f.render_widget(paragraph, chunks[0]);

let paragraph = Paragraph::new("分享 GitHub 上有趣、入門級(jí)的開源項(xiàng)目")
.style(Style::default().bg(Color::White).fg(Color::Black))
.block(Block::default().borders(Borders::ALL).title("宗旨"))
.alignment(Alignment::Center);
f.render_widget(paragraph, chunks[1]);
}

這些代碼可能看起來(lái)不少,但大部分都是固定的模板,不需要我們每次的重新構(gòu)思。下面,就讓我們來(lái)詳細(xì)了解其中的細(xì)節(jié)。

2.2 創(chuàng)作模板

官方通過(guò) example 給出了使用 tui.rs 進(jìn)行設(shè)計(jì)的模板,我希望各位讀者在使用時(shí)也能遵守這套模板以保證程序的可讀性。

一個(gè)使用 tui.rs 程序的一生大概是這樣的:

其模塊可以大致分為:

  • app.rs 實(shí)現(xiàn) App 結(jié)構(gòu)體,用于處理 UI 邏輯,保存 UI 狀態(tài)
  • ui.rs 實(shí)現(xiàn) UI 渲染功能

但對(duì)于小型程序來(lái)講,也可以都寫在 main.rs 之中。

首先來(lái)看開始和結(jié)束部分關(guān)于 Terminal 的操作,每次運(yùn)行都會(huì)保存原始 Terminal 界面內(nèi)容并在一個(gè)新的窗體上運(yùn)行,在結(jié)束后又會(huì)恢復(fù)到原來(lái)的 Terminal 窗體中,有效地防止了搞亂原來(lái)的窗口內(nèi)容。這部分代碼模板官方已經(jīng)給出,基本無(wú)需修改:

fn main() -> Result<(), io::Error> {
// 配置 Terminal
enable_raw_mode()?; // 啟動(dòng)命令行的 raw 模式
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; // 在一個(gè)新的界面上運(yùn)行 UI,保存原終端內(nèi)容,并開啟鼠標(biāo)捕獲
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
// 初始化 app 資源
let mut app = App {
url: String::from(r"https://hellogithub.com/"),
};
// 程序主要邏輯循環(huán) …… //
run_app(&mut terminal, app)?;
// 恢復(fù) Terminal
disable_raw_mode()?; // 禁用 raw 模式
execute!(
terminal.backend_mut(),
LeaveAlternateScreen, // 恢復(fù)到原來(lái)的命令行窗口
DisableMouseCapture // 禁用鼠標(biāo)捕獲
)?;
terminal.show_cursor()?; // 顯示光標(biāo)

Ok(())
}

接下來(lái)是處理 UI 邏輯的 run_app 函數(shù),我們?cè)诖颂幚碇T如 用戶按鍵、UI 狀態(tài)更改等邏輯:

fn run_app(terminal: &mut Terminal, mut app: App) -> io::Result<()> {
loop {
// 渲染 UI
terminal.draw(|f| ui(f, &mut app))?;
// 處理按鍵事件
if crossterm::event::poll(Duration::from_secs(1))? { // poll 方法非阻塞輪詢
if let Event::Key(key) = event::read()? { // 直接 read 如果沒(méi)有事件到來(lái)則會(huì)阻塞等待
match key.code { // 判斷用戶按鍵
KeyCode::Char(ch) => {
if 'q' == ch {
break;
}
}
_ => {}
}
}
}
// 處理其他邏輯
}
Ok(())
}

對(duì)于功能簡(jiǎn)單的界面來(lái)講,這個(gè)函數(shù)作用不大。但如果我們的程序需要更新一些組件狀態(tài)(比如列表選中項(xiàng)、用戶輸入、外界數(shù)據(jù)交互等)則應(yīng)在此統(tǒng)一處理。

之后,我們會(huì)使用 terminal.draw() 方法繪制界面,其接受一個(gè)閉包:

fn ui(f: &mut Frame, app: &mut App) {
// 獲取分割后的窗口
let chunks = Layout::default() // 首先獲取默認(rèn)構(gòu)造
.constraints([Constraint::Length(3), Constraint::Min(3)].as_ref()) // 按照 3 行 和 最小 3 行的規(guī)則分割區(qū)域
.direction(Direction::Vertical) // 垂直方向分割
.split(f.size()); // 分割整塊 Terminal 區(qū)域
let paragraph = Paragraph::new(Span::styled(
app.url.as_str(),
Style::default().add_modifier(Modifier::BOLD),
))
.block(Block::default().borders(Borders::ALL).title("HelloGitHub"))
.alignment(tui::layout::Alignment::Left);
f.render_widget(paragraph, chunks[0]);

let paragraph = Paragraph::new("分享 GitHub 上有趣、入門級(jí)的開源項(xiàng)目")
.style(Style::default().bg(Color::White).fg(Color::Black))
.block(Block::default().borders(Borders::ALL).title("宗旨"))
.alignment(Alignment::Center);
f.render_widget(paragraph, chunks[1]);
}

在這里,有如下流程:

  • 使用 Layout 按照需求給定 Constraint 切分窗體,獲取 chunks,每個(gè) chunk 也可以利用 Layout 繼續(xù)進(jìn)行分割
  • 實(shí)例化組件,每個(gè)組件都實(shí)現(xiàn)了 default 方法,在使用時(shí)我們應(yīng)該先使用 xxx::default() 獲取默認(rèn)對(duì)象,再利用默認(rèn)對(duì)象更新組件樣式。例如 Block::default().borders(Borders::ALL) 、Style::default().bg(Color::White) 等。這也是官方推薦做法。
  • 使用 f.render_widget 渲染組件到窗體上,對(duì)于類似 列表 等存在狀態(tài)(比如當(dāng)前選中元素)的組件,則使用 f.render_stateful_widget 進(jìn)行渲染

關(guān)于 tui.rs 其他內(nèi)置組件的使用方法,可以查看官方的 example 文件,編寫套路是一樣的,可以根據(jù)需要直接復(fù)制粘貼。

需要注意到是,在此我們只關(guān)心 UI 組件的顯示方式和內(nèi)容,有關(guān)程序邏輯的內(nèi)容應(yīng)放在 run_app 中處理以免打亂程序架構(gòu)或影響 UI 繪制效果(你總不希望 UI 繪制到一半的時(shí)候因?yàn)檫M(jìn)行了某些 IO 操作而卡住了對(duì)吧?)

到這里對(duì)于 tui.rs 的介紹就結(jié)束了,實(shí)際上使用 tui.rs 編寫 UI 界面很簡(jiǎn)單,只要根據(jù)創(chuàng)作模板結(jié)合官方例子一步步構(gòu)建,任何人都可以很快上手。

三、更多實(shí)用工具

下面將介紹介紹幾款基于 tui.rs 構(gòu)建的流行開源項(xiàng)目,它們無(wú)一例外是命令行工具里的“神兵利器“!

3.1 實(shí)時(shí)股票數(shù)據(jù)

支持查看不同時(shí)間維度以及交易量等數(shù)據(jù),股票實(shí)時(shí)數(shù)據(jù)來(lái)自雅虎。

地址:https://github.com/tarkah/tickrs

3.2 文件傳輸工具

支持 SCP/SFTP/FTP/S3 功能豐富的終端文件傳輸工具。

地址:https://github.com/veeso/termscp

3.3 網(wǎng)絡(luò)監(jiān)控工具

用于按進(jìn)程、連接、遠(yuǎn)程 IP、主機(jī)名顯示當(dāng)前網(wǎng)絡(luò)利用率。

地址:https://github.com/imsnif/bandwhich


分享名稱:高手過(guò)招不用鼠標(biāo),一款超好用的跨平臺(tái)命令行界面庫(kù)
瀏覽路徑:http://www.5511xx.com/article/cdogjdp.html