文章目录

  • 下载和演示
  • 配置文件
  • 源代码


下载和演示

首先下载其源代码egui,然后进入其example文件夹,进入之后,使用cargo命令进行编译

cargo run --release -p hello_world

rust会自动下载一些相关的包和库,编译运行后,结果如下

rust 图形学习_rust 图形学习

同时根目录下会出现一个Target文件夹,占据了400多兆的硬盘空间,这里记录了cargo编译的过程,并且最后得到的可执行文件也在其中。但这个可执行文件hello_world.exe的尺寸控制的还可以,只有不到6M。

hello_world是egui中最简单的示例,其文件结构也非常简单,只有一个配置文件和一个main源代码,目录层级如下

  • src
  • main.rs
  • Cargo.toml

下面分别对这两个文件进行简要的介绍。

配置文件

Cargo.toml的文件内容如下,前面诸如名字、版本等信息无关紧要,但后面的依赖项需要注意,给定了eframe的位置。

[package]
name = "hello_world"
version = "0.1.0"
authors = ["Emil Ernerfeldt <emil.ernerfeldt@gmail.com>"]
license = "MIT OR Apache-2.0"
edition = "2021"
rust-version = "1.70"
publish = false


[dependencies]
eframe = { path = "../../crates/eframe", features = [
    "__screenshot", # __screenshot is so we can dump a screenshot using EFRAME_SCREENSHOT_TO
] }
env_logger = "0.10"

源代码

首先,源代码第一行用于隐藏Window命令行,然后调用eframe中的egui库。

#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use eframe::egui;

接下来就是main函数,内容如下,首先设置一个参数变量,里面包含了窗口的初始尺寸;然后执行run_native,即开启窗口,里面有三个参数,分别是窗口名称、刚刚创建的参数文件,以及最重要的,一个新建的App窗口。

fn main() -> Result<(), eframe::Error> {
    env_logger::init(); 
    let options = eframe::NativeOptions {
        initial_window_size: Some(egui::vec2(320.0, 240.0)),
        ..Default::default()
    };
    eframe::run_native(
        "My egui App",
        options,
        Box::new(|_cc| Box::<MyApp>::default()),
    )
}

在main函数中,用到了Box::<MyApp>,其中MyApp是一个自定义的结构体,内容如下,其中主要有两个变量,分别是字符串类型的name和整型的age。

然后为其绑定Default方法,给出了默认姓名和年龄,这两步显然没什么好说的。

struct MyApp {
    name: String,
    age: u32,
}

impl Default for MyApp {
    fn default() -> Self {
        Self {
            name: "Arthur".to_owned(),
            age: 42,
        }
    }
}

接下来则是关键内容,为MyApp绑定了eframe中的方法。

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            ui.heading("My egui Application");
            ui.horizontal(|ui| {
                let name_label = ui.label("Your name: ");
                ui.text_edit_singleline(&mut self.name)
                    .labelled_by(name_label.id);
            });
            ui.add(egui::Slider::new(&mut self.age, 0..=120).text("age"));
            if ui.button("Click each year").clicked() {
                self.age += 1;
            }
            ui.label(format!("Hello '{}', age {}", self.name, self.age));
        });
    }
}

下面逐条拆解,首先ui.heading用于标识窗口名。

ui.horizontal是一个水平的布局框,其内部的元素横向布置。在上述代码中,里面摆放了一个写着Your name的label标签,以及一个可编辑的文本框。

接下来,添加一个滚动条,滚动条的范围是0到120,滚动条的标记是age。

最后两行,一个按钮,一个标签。当按钮被点击时,self.age加一,相应地绑定self.age的控件也会跟着发生变化。