注:此文適合于對rust有一些了解的朋友
iced是一個跨平臺的GUI庫,用于為rust語言程序構建UI界面。
?
iced的基本邏輯是:
UI交互產生消息message,message傳遞給后臺的update,在這個函數中編寫邏輯,然后通過View函數更新UI。
- Take the result of our view logic and layout its widgets.
獲取視圖邏輯的結果并布局其小部件。- Process events from our system and produce messages for our update
logic. 處理來自系統的事件,并為我們的更新邏輯生成消息。- Draw the resulting user interface. 繪制生成的用戶界面。
下面我們將通過舉例來說明iced如何顯示一個窗口,以及如何在窗口上顯示中文。
一、如何用iced構建窗口:
我們構建一個基本窗口,窗口有一個按鈕,一個文本框,一個標簽,在文本框輸入字符,點擊按鈕后,標簽上顯示相同內容。
UI實例預覽:
1 導入庫
use iced::widget::{button, column, text, text_input};
use iced::{Alignment, Element, Sandbox, Settings};
2、配置Cargo.toml
[dependencies]
iced="0.10"
這樣,使用cargo check時,會自動安裝iced庫。
3、構建窗口程序
主函數:
pub fn main() -> iced::Result { Counter::run(Settings::default()) //此處為使用默認窗口設置}
定義數據結構:
//創建結構體struct
struct Counter{value: String,value2:String,
}
定義消息:
#[derive(Debug, Clone)] //為下方的enum添加特性trait
enum Message {Showtext,InputChanged(String),
}
實現一個實例:
//sandbox是一個trait
impl Sandbox for Counter { //impl將sandbox添加給Counter,使Counter具有了sandbox的一些特性type Message = Message; fn new() -> Self { //初始化sandbox,返回初始值Self { value: String::new(),value2:String::new(),}}fn title(&self) -> String { //返回sandbox的標題String::from("iced_UI")}fn update(&mut self, message: Message) { //此處書寫更新邏輯程序,所有UI交互會在這里處理match message {Message::Showtext=> { let ss=&self.value; self.value2=ss.to_string(); }Message::InputChanged(value) =>{self.value=value;}}}fn view(&self) -> Element<Message> { column![text_input("enter some string",&self.value).on_input(Message::InputChanged).padding(10).size(16),button("push").on_press(Message::Showtext).padding(2).width(40), text(format!("enter text:{}",&self.value2)).size(16), ].spacing(10).padding(6).align_items(Alignment::Center).into()}}
完整代碼:
use iced::widget::{button, column, text, text_input};
use iced::{Alignment, Element, Sandbox, Settings};pub fn main() -> iced::Result {Counter::run(Settings::default()) //此處為使用默認窗口設置}//創建結構體struct
struct Counter{value: String,value2:String,
}#[derive(Debug, Clone)] //為下方的enum添加特性trait
enum Message {Showtext,InputChanged(String),
}//sandbox是一個trait
impl Sandbox for Counter { //impl將sandbox添加給Counter,使Counter具有了sandbox的一些特性type Message = Message;fn new() -> Self { //初始化sandbox,返回初始值Self { value: String::new(),value2:String::new(),}}fn title(&self) -> String { //返回sandbox的標題String::from("iced_UI")}fn update(&mut self, message: Message) { //此處書寫更新邏輯程序,所有UI交互會在這里處理match message {Message::Showtext=> { let ss=&self.value; self.value2=ss.to_string(); }Message::InputChanged(value) =>{self.value=value;}}}fn view(&self) -> Element<Message> { column![text_input("enter some string",&self.value).on_input(Message::InputChanged).padding(10).size(16),button("push").on_press(Message::Showtext).padding(2).width(40), text(format!("enter text:{}",&self.value2)).size(16), ].spacing(10).padding(6).align_items(Alignment::Center).into()}}
cargo run以上代碼,演示如下:
由于涉及rust和iced兩個方面的應用,在此,僅就iced的相關使用作一下說明,至于對rust的代碼有疑問的,可以參考rust的官方手冊。
impl Sandbox for Counter{}
這里的sandbox是iced庫提供的一個簡單的應用特性,它是一個trait,有update、view、run等函數功能,此處,update和view是兩個有點對應的功能,當你在UI操作部件時,會產生交互消息message,update就是接受message的,你可以在update函數下,編寫你的邏輯:
此例中,我的邏輯是,當在文本框輸入信息時,實時文本會傳給之前定義好的一個數據即value。當點擊按鈕時,會將文本框的數據傳給另一個數據value2,然后value2是和用于顯示的文本框綁定的。
fn update(&mut self, message: Message) { //此處書寫更新邏輯程序,所有UI交互會在這里處理match message { Message::Showtext=> { let ss=&self.value; self.value2=ss.to_string(); }Message::InputChanged(value) =>{self.value=value;}}}
value2通過view函數顯示到UI界面。
下面的代碼是其中一句,這里將text部件綁定了一個值self.value2即前面定義的value2。
text(format!("enter text:{}",&self.value2)).size(16),
二、如何在iced窗口顯示中文:
但是上面的程序,有個小小的不足,就是窗口無法顯示中文字符,比如,我將按鈕的名稱由push改成開始:
button("開始")
再運行的話:
可以看到上圖中按鈕的名字變成了亂碼,這是因為在窗口的設定時,使用了默認參數:
pub fn main() -> iced::Result {Counter::run(Settings::default()) //此處為使用默認窗口設置
}
就是此處的Settings,而iced的默認窗口參數中,字體使用的是:SansSerif。因此不支持中文字符,所以,如果想要在UI界面用中文來表示各個部件的名稱或注釋,需要更改字體。
所以,此處我們對上面的程序進行修改,以便窗口可以顯示中文,其實就是修改字體的設置。
首先需要添加導入:
use iced::Font;
use iced::font::Family;
然后,修改主函數中的run函數的Settings:
pub fn main() -> iced::Result { //Counter::run(Settings::default()) //此處為使用默認窗口設置 let ff="Microsoft YaHei"; //設置自定義字體Counter::run(Settings {default_font:Font{ //設置自定義字體,用于顯示中文字符family:Family::Name(ff),..Font::DEFAULT},..Settings::default()})
}
和之前的主函數對一下,可以發現,這里我先定義了一個字符串,用來表示字體的名字,此處是微軟雅黑字體。
然后在Settings中,將關于字體的default_font單獨設置。
設置好后,我們再來cargo run一下:
可以看到,中文字符能正常顯示了。
對上面的主函數,我們再做一下修改,使窗口啟動時的尺寸按照我們想要的來,即自定義窗口尺寸:
先添加導入
use iced::window;
然后主函數:
pub fn main() -> iced::Result { //Counter::run(Settings::default()) //此處為使用默認窗口設置 let ff="Microsoft YaHei"; //設置自定義字體Counter::run(Settings {window:window::Settings{ //設置自定義窗口尺寸size:(600,400),..window::Settings::default()},default_font:Font{ //設置自定義字體,用于顯示中文字符family:Family::Name(ff),..Font::DEFAULT},..Settings::default()})
}
這樣一來,窗口啟動時不會按照默認的來,而是按照自己設定來顯示。