文章目录
egui教程:egui下载和创建流程⚙️程序结构
目标与源代码
本文介绍图形界面开发过程中最常用的几个组件,即标签、文本输入框、下拉框、滑块以及按钮,如下图所示

完整代码如下
rust
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use eframe::egui;
struct MyApp {
name: String,
age: u32,
gender: String,
}
impl Default for MyApp {
fn default() -> Self {
Self {
name: "Arthur".to_owned(),
gender: "Male".to_owned(),
age: 42,
}
}
}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("self-introduction");
ui.horizontal(|ui| {
ui.label("name: ");
ui.text_edit_singleline(&mut self.name);
});
ui.horizontal(|ui|{
egui::ComboBox::from_label("gender")
.selected_text(self.gender.clone())
.show_ui(ui, |ui| {
ui.selectable_value(&mut self.gender, "Male".to_owned(), "Male");
ui.selectable_value(&mut self.gender, "Female".to_owned(), "Female");
});
});
ui.horizontal(|ui|{
ui.add(egui::Slider::new(&mut self.age, 0..=120).text("age"));
if ui.button("add one").clicked() {
self.age += 1;
}
});
ui.label(format!("I'm {}, {} years old, {}", self.name, self.age, self.gender));
});
}
}
fn main() -> Result<(), eframe::Error> {
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([300.0, 150.0]),
..Default::default()
};
eframe::run_native(
"self introduce",
options,
Box::new(|_cc| Ok(Box::<MyApp>::default())),
)
}
eframe的程序架构,以及在运行过程中必备的【run_native】、【options】、【update】在前面已经讲过,本文将主要针对这几个组件进行简单的讲解,这些组件粗略可分为三类
- 布局组件【egui::CentralPanel】、【ui.horizontal】
- 标签组件【ui.heading】、【ui.label】
- 功能组件【ui.text_edit_singleline】、【egui::ComboBox】、【egui::Slider】【ui.button】
布局组件
【CentralPanel】首先是一种Panel,即面板,在本文的程序中起到了主界面的作用。在实际编程时,这个组件必须放在其他Panel最后,例如SidePanel、TopBottomPanel等。这些面板顾名思义,CentralPanel即居中的面板,以此类推。
Panel支持更改背景色,只需在default()之后、show()之前添加frame方法即可,示例如下
rust
egui::CentralPanel::default()
.frame(
egui::Frame::none()
.fill(egui::Color32::from_rgb(30, 30, 30)) // 设置背景色为深灰色
.inner_margin(egui::Vec2::new(10.0, 10.0)) // 可选:内边距
)
.show(/*之前那一大坨*/);
【ui.horizontal】也故名思意,是一种水平布局方案,其内部装载的组件将沿着水平方向一字排开。
和Panel不同,horizontal是定义在ui模块中的一个函数,Panel则是个结构体。所以,在使用Panel的时候,可以通过链式表达式,先调用default初始化,然后通过frame调整属性,最后使用show完成内部组件的装载。相比之下,horizontal就简单多了,只有一个参数add_contents。
【add_contents】本身又是一个闭包形式的函数,其普普通通的样子如下
rust
fn show_name(&mut self, ui: &mut egui::Ui) {
ui.label("name: ");
ui.text_edit_singleline(&mut self.name);
}
其中,函数名是额外加上的,这个无需多言。但是【self】则很有说法,在【show】函数中,将其自身直接传给了闭包,所以无需再写一次。
功能组件
标题文字【ui.heading】和标签【ui.label】相对来说比较简单,就不单独讲解了。
【text_edit_singleline】是单行可输入文本,其使用方法也非常简单,只需传入一个变量以绑定文本框中的文本即可。
【button】也很简单,输入参数为按钮上的文字,在.click()后面绑定点击后的动作。
这个时候你可能会感到有些不对劲,因为按钮本该是个非常复杂的组件,怎么egui中就用一个函数就搞定了?如果我想双击怎么办?
因为实际上,【ui.button(text)】是【ui.add(Button::new(text))】的缩写,前面提到过的这几种组件也是同样的原理,例如【ui.label("name:")】就可以写成
rust
ui.add(egui::Label::new("name: "));
总结一下,纵观我们调用的这些组件,主要来自两个结构体,分别是Ui和Widget。其中Ui里的组件以函数形式调用,Widget中的组件以结构体的形式调用。其中,ui.label更加简洁。
但滑块【Slider】和下拉选框【Combobox】在Ui中哦个并没有这种简洁的调用函数,所以只能从【egui::】中拿出结构体的new方法来创建。