学习了一段rust之后,有点技痒是否能用rust做一个带界面的demo。于是调查一番最后选择了GTK-rs作为UI库。接下来就一步步演示下,如果使用GTK完成基于rust的简单小应用。
首先根据官网提示,在cargo.toml中增加相关依赖
[dependencies.gtk]
version = "0.8.0"
features = ["v3_16"]
[dependencies.gio]
version = ""
features = ["v2_44"]
接着创建main.rs文件 ,导入gtk库。
extern crate gtk;
extern crate gio;
use gtk::prelude::*;
use gio::prelude::*;
添加main函数 ,new 一个Application对象出来,如果运行cargo run就会发现一个空白界面就出来了。
fn main() {
let application = Application::new(
Some("com.github.gtk-rs.examples.basic"),
Default::default(),
).expect("failed to initialize GTK application");
application.connect_activate(|app| {
let window = ApplicationWindow::new(app);
window.set_title("HelloRust");
window.set_default_size(350, 70);
window.show_all();
});
application.run(&[]);
}
在这个空白界面上添加一个输入框,再添加几个按钮。
let outer_box = gtk::Box::new(gtk::Orientation::Vertical, 0);
let inner_box = gtk::Box::new(gtk::Orientation::Horizontal, 0);
let entry: Entry = gtk::Entry::new();
entry.set_size_request(500, 15);
entry.set_margin_start(10);
entry.set_margin_end(10);
entry.set_margin_top(10);
entry.set_max_width_chars(20);
let brief = gtk::TextView::new();
brief.set_halign(gtk::Align::Start); // 10 pixel right margin
brief.set_editable(false);
brief.set_size_request(500, 30);
brief.get_buffer().unwrap().set_text("收款方(Bob)地址:XXX.XXX.XXX.XXX");
brief.set_margin_start(10);
brief.set_margin_end(10);
brief.set_margin_top(20);
brief.override_background_color(
gtk::StateFlags::from_bits(gtk::StateFlags::NORMAL.bits()).unwrap(),
Some(&RGBA {
red: 0.965,
green: 0.96,
blue: 0.957,
alpha: 1f64,
}),
);
let mut details = gtk::TextView::new();
details.set_halign(gtk::Align::Start); // 10 pixel right margin
details.set_editable(false);
details.set_size_request(50, 30);
details.get_buffer().unwrap().set_text("金额:");
details.set_margin_start(10);
details.set_margin_end(10);
details.set_margin_top(20);
details.override_background_color(
gtk::StateFlags::from_bits(gtk::StateFlags::NORMAL.bits()).unwrap(),
Some(&RGBA {
red: 0.965,
green: 0.96,
blue: 0.957,
alpha: 1f64,
}),
);
let button = Button::new_with_label("Alice发起转账");
button.set_size_request(300, 20);
button.set_margin_start(30);
button.set_margin_end(30);
button.set_margin_top(30);
let confirm_button = Button::new_with_label("Bob确认交易并签名");
confirm_button.set_size_request(300, 20);
confirm_button.set_margin_start(30);
confirm_button.set_margin_end(30);
confirm_button.set_margin_top(30);
let verify_button = Button::new_with_label("Alice校验交易合法性");
verify_button.set_size_request(100, 20);
verify_button.set_margin_start(30);
verify_button.set_margin_end(30);
verify_button.set_margin_top(30);
let logtext = gtk::TextView::new();
logtext.set_halign(gtk::Align::Start); // 10 pixel right margin
logtext.set_editable(false);
logtext.set_size_request(950, 300);
logtext.get_buffer().unwrap().set_text("");
logtext.set_margin_start(10);
logtext.set_margin_end(10);
logtext.set_margin_top(20);
分别将这些控件,添加到box中。因为我想做横排,竖排两种布局所以定义了两个box:
inner_box.pack_start(&details, false, false, 0);
inner_box.pack_start(&entry, false, false, 0);
outer_box.pack_start(&brief, false, false, 0);
outer_box.pack_start(&inner_box, false, false, 0);
outer_box.pack_start(&button, false, false, 0);
outer_box.pack_start(&confirm_button, false, false, 0);
outer_box.pack_start(&verify_button, false, false, 0);
outer_box.pack_start(&logtext, false, false, 0);
window.add(&outer_box);
界面布局大功告成,我们接着给按钮增加监听事件。
let amount_buffer = entry.get_buffer();
button.connect_clicked(move |_| {
let re = Regex::new(r"^[0-9]*[1-9][0-9]*$").unwrap();
let amount = amount_buffer.get_text();
if re.is_match(&amount) {
//输入金额合法
} else {
//请输入正确的金额,需是正整数
}
});
这样就如愿给amount按钮增加了一个点击事件。点击该按钮后就可以获取entry里的输入值,并在事件监听函数connect_clicked里做正则匹配了 。
好啦,运行一下,看看结果。