资讯动态

egui 与 eframe 官方示例仓库指南:从 Hello World 到自定义渲染的完整实践路线

发布时间:2026/9/11 16:30:13 来源:尧图企业网站定制
egui 与 eframe 官方示例仓库指南从 Hello World 到自定义渲染的完整实践路线【免费下载链接】eguiegui: an easy-to-use immediate mode GUI in Rust that runs on both web and native项目地址: https://gitcode.com/GitHub_Trending/eg/egui本指南围绕 egui 仓库中的 examples 目录展开它是学习和复用 egui 即时模式 GUI 最直接的一手素材库每个示例都以eframe搭建原生窗口覆盖 UI 控件、自定义字体、文件对话框、多窗口、3D 渲染与 Web 运行等常见场景。读完本文你将掌握示例的运行方式、目录结构、每个示例的核心技术与适用场景并能基于hello_world模板快速搭建自己的 egui 应用。examples 目录是什么examples/目录是 egui 官方维护的示例集合其定位在 examples/README.md 中写得很清楚该目录下所有示例都使用eframe来为一个egui应用创建窗口完成窗口托管 事件循环 渲染后端这一整套引导工作部分示例是eframe特有的例如自定义原生窗口装饰、多视口但绝大多数 UI 代码对所有 egui 集成方式如 egui-winit、egui_glow、egui-wgpu 或纯 Web 环境同样适用每个示例都是一个独立可cargo run的 crate带独立的Cargo.toml、README.md与运行截图。从仓库结构看Cargo.toml 工作区 examples/ 目录每个子目录即一个独立示例 crate命名即主题例如hello_world、custom_3d_glow、multiple_viewports。全部示例可通过 examples/run_all.sh 一键顺序运行for example_name in *; do if [ -d $example_name ]; then cargo run --quiet -p $example_name fi done该脚本用cargo run -p crate名的方式逐个启动目录下的示例要求在当前工作区根目录或 examples 目录执行cargo这也是各示例 README 中统一推荐的运行方式例如cargo run -p hello_world cargo run -p custom_3d_glow版本与文档配套说明原 README 特别强调了两点使用前提本仓库现状与其完全吻合main 分支的示例对应最新开发版 egui仓库根目录的 rust-toolchain 指定了工具链示例 crate 的Cargo.toml如 examples/hello_world/Cargo.toml声明rust-version 1.95与edition 2024且依赖以workspace true方式引用 Cargo.toml 中定义的eframe、egui_extras等 crate。因此这些示例依赖较新的 Rust 版本与最新 API请使用较新的工具链编译。若要针对特定版本查找示例需切换到对应版本的 tag如latest再查看该 tag 下的examples目录而不是在 main 分支上直接套用旧版本代码。官方还提供两类补充资料egui.rs 官网的在线示例每个都附源码链接以及 egui 与 eframe 的 API 文档docs.rs。本仓库内的文档如 ARCHITECTURE.md、RELEASES.md 也可帮助你理解版本演进与架构背景。最小可运行示例hello_world 与 hello_world_simple经典模板 hello_worldexamples/hello_world/src/main.rs 是控件演示与模板双重定位的最小完整应用完整代码如下#![cfg_attr(not(debug_assertions), windows_subsystem windows)] // hide console window on Windows in release #![expect(rustdoc::missing_crate_level_docs)] // its an example use eframe::egui; fn main() - eframe::Result { env_logger::init(); // Log to stderr (if you run with RUST_LOGdebug). let options eframe::NativeOptions { viewport: egui::ViewportBuilder::default().with_inner_size([320.0, 240.0]), ..Default::default() }; eframe::run_native( My egui App, options, Box::new(|cc| { // This gives us image support: egui_extras::install_image_loaders(cc.egui_ctx); Ok(Box::MyApp::default()) }), ) } struct MyApp { name: String, age: u32, } impl Default for MyApp { fn default() - Self { Self { name: Arthur.to_owned(), age: 42, } } } impl eframe::App for MyApp { fn ui(mut self, ui: mut egui::Ui, _frame: mut eframe::Frame) { egui::CentralPanel::default().show(ui, |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(Increment).clicked() { self.age 1; } ui.label(format!(Hello {}, age {}, self.name, self.age)); ui.image(egui::include_image!( ../../../crates/egui/assets/ferris.png )); }); } }这个示例浓缩了 egui 应用的完整骨架逐段拆解如下平台引导eframe::run_native(name, options, app_creator)是原生桌面入口。eframe::Result是统一的错误返回类型NativeOptions通过viewport: egui::ViewportBuilder配置窗口属性此处设with_inner_size([320.0, 240.0])指定初始窗口大小。应用状态即结构体MyApp { name, age }直接作为即时模式 UI 的状态载体Default提供初始值。即时模式的核心特征就在这里——每次帧重绘时 UI 都会按当前状态重建状态由你的结构体持有。UI 组装CentralPanel提供中央面板布局heading、label、text_edit_singleline、Slider、button覆盖文本、输入、滑动条、按钮四类基础控件Slider::new(mut self.age, 0..120)双向绑定状态与范围。图片资源egui_extras::install_image_loaders(cc.egui_ctx)安装图片加载器随后用egui::include_image!宏把仓库内的 crates/egui/assets/ferris.png 编译进二进制并直接绘制。其Cargo.tomlexamples/hello_world/Cargo.toml的依赖结构同样值得借鉴eframe { workspace true, features [ default, __screenshot, # __screenshot is so we can dump a screenshot using EFRAME_SCREENSHOT_TO ] } # For image support: egui_extras { workspace true, features [default, image] } env_logger { workspace true, features [auto-color, humantime] }要点eframe自带egui代码里直接use eframe::egui需要图片显示时启用egui_extras的imagefeature__screenshotfeature 配合环境变量EFRAME_SCREENSHOT_TO可在 CI 中自动输出截图这正是仓库 scripts/generate_example_screenshots.sh 批量生成示例截图所依赖的机制。更精简的 hello_world_simple如果你只想看最少的 egui 程序examples/hello_world_simple/src/main.rs 只用了约 30 行它省去自定义App结构体改用eframe::run_ui_native直接以闭包形式书写 UI局部变量name、age由闭包捕获功能与hello_world完全一致eframe::run_ui_native(My egui App, options, move |ui, _frame| { egui::CentralPanel::default().show(ui, |ui| { ui.heading(My egui Application); ui.horizontal(|ui| { let name_label ui.label(Your name: ); ui.text_edit_singleline(mut name) .labelled_by(name_label.id); }); ui.add(egui::Slider::new(mut age, 0..120).text(age)); if ui.button(Increment).clicked() { age 1; } ui.label(format!(Hello {name}, age {age})); }); })对比可见当应用逻辑简单、无需保留结构化状态时run_ui_native是更轻量的选择当应用复杂多窗口、需要CreationContext做初始化、需要on_exit清理资源时run_nativeimpl eframe::App才是正确姿势。进阶示例导读按主题挑选你的参考实现examples 目录覆盖了从控件用法到渲染后端深度定制的完整梯度以下按主题梳理每个示例的核心价值对应源码均在各自src/main.rs运行命令见各目录 README窗口与视口管理示例主题关键技术点confirm_exit退出确认拦截关闭事件、弹出确认对话框custom_window_frame自定义窗口装饰ViewportBuilder::with_decorations(false)、with_transparent(true)隐藏系统边框配合clear_color返回透明色用ViewportCommand::StartDrag/Maximized/Close等命令自绘标题栏与窗口按钮multiple_viewports多窗口一个进程中创建多个原生窗口视口serial_windows顺序窗口依次弹出多个窗口的流程控制window_options在 demo lib 中窗口选项窗口参数调节参考custom_window_frame是eframe特有的高级用法其实现思路值得细读examples/custom_window_frame/src/main.rs先用with_decorations(false)隐藏系统标题栏、with_transparent(true)启用透明以支持圆角然后在App::clear_color中返回egui::Rgba::TRANSPARENT避免圆角外区域被底色覆盖自绘标题栏时用ui.interact(rect, Id::new(title_bar), Sense::click_and_drag())捕获拖拽双击切换最大化ViewportCommand::Maximized(!is_maximized)拖拽时发送ViewportCommand::StartDrag让系统接管窗口移动。输入与系统集成示例主题关键技术点keyboard_events键盘事件事件回调与按键状态查询file_dialog文件对话框与拖放rfd::FileDialog::new().pick_file()打开原生对话框with_drag_and_drop(true)启用拖放从ui.input(|i| i.raw.dropped_files / hovered_files)读取拖入与悬停文件并用LayerId::new(Order::Foreground, ...)绘制拖放悬停遮罩预览custom_keypad自定义输入面板组合自定义按键 UI 与文本输入user_attention窗口注意力闪烁/提醒用户注意的窗口操作file_dialog同时展示了原生与 Web 两种文件处理路径examples/file_dialog/src/main.rs原生端用file.path()拿路径wasm32目标下改用file.web_file()获取文件名、MIME 类型与大小#[cfg(...)]条件编译分平台实现。字体与主题示例主题关键技术点custom_font自定义字体两种方式ctx.add_font(FontInsert::new(...))增量添加字体并指定家族优先级ctx.set_fonts(fonts)整体替换FontDefinitions把自定义字体insert(0, ...)到Proportional首位、push到Monospace末尾作回退。include_bytes!内嵌仓库中的 crates/epaint_default_fonts/fonts/Hack-Regular.ttf.ttf/.otf均支持custom_font_style字体样式字号、字重、斜体等样式控制font_variations可变字体使用仓库内的 examples/font_variations/data/Recursive-VariableFont.ttf 演示字重连续变化custom_style自定义样式修改Style/Visuals全局换肤styling_engine样式引擎类class与原子样式等新样式系统的应用渲染与特效示例主题关键技术点custom_3d_glow自定义 3D 渲染OpenGLeframe::Renderer::Glow指定后端通过egui::PaintCallback把glow的 GPU 绘制注入 egui 渲染流程资源放在ArcMutex...中以便在回调里使用App::on_exit中销毁 GL 程序images图片显示仓库内 examples/images/src/ferris.svg、examples/images/src/cat.webp、examples/images/src/ferris.gif 分别演示 SVG / WebP / GIF 三种格式的加载与动画screenshot截图功能ScreenshotCallback把当前帧保存为图片puffin_profiler性能分析集成 puffin 对 egui 应用做 CPU 采样分析fractal_clock在 demo lib 中分形时钟动画动画驱动的绘制参考custom_3d_glow是egui 中嵌入原生 GPU 渲染的范本examples/custom_3d_glow/src/main.rs用ui.allocate_exact_size(egui::Vec2::splat(300.0), egui::Sense::drag())预留 300×300 的画布并接收拖拽输入把旋转角写入egui_glow::CallbackFn闭包构造egui::PaintCallback { rect, callback }交给ui.painter().add(...)渲染闭包内直接调用glowAPI 编译着色器、gl.draw_arrays绘制三角形。注意着色器版本按平台分支wasm32 用#version 300 es原生用#version 330。事件循环与异步示例主题关键技术点external_eventloop外部事件循环不依赖run_native自行驱动事件循环将 egui 集成进既有主循环external_eventloop_async异步事件循环在异步运行时pollster/async中驱动 eframe代码拆分在 examples/external_eventloop_async/src/main.rs 与 examples/external_eventloop_async/src/app.rshello_androidAndroid 平台egui/eframe 在移动端Android的最小运行示例hello_world_par并行渲染多线程rayon 风格渲染参考弹层与交互示例主题关键技术点popups弹出层Area/Popup相关弹层组合用法hello_world基础控件Label、TextEdit、Slider、Button入门见上文完整代码示例之外把 demo 跑起来与进一步深入更丰富的演示应用除examples/外仓库还提供了体量更大、覆盖更全的演示程序适合系统性探索 egui 能力egui_demo_app完整的演示应用含egui_demo_lib中数十个 demo 页面widget 画廊、窗口选项、文本布局、绘图、表格、颜色选择器等源码在 egui_demo_lib/src/demo/ 按主题分文件组织其 tests/snapshots/ 下的渲染快照既是回归测试也是视觉效果合集examples/run_all.sh 可一次跑遍全部 examples仓库 scripts/ 下的build_demo_web.sh、setup_web.sh等脚本说明了如何把 demo 编译到 Webwasm运行这也印证了 README 中许多示例适用于任何 egui 集成的说法——同一套 UI 代码可在原生与浏览器两种环境复用。阅读顺序建议先跑hello_world或更精简的hello_world_simple对照上文代码理解run_nativeApp::ui骨架按业务需求横向取用进阶示例做工具软件看custom_window_frame、file_dialog、confirm_exit做展示/游戏类看custom_3d_glow、images做跨平台/Web 应用看external_eventloop系列与hello_android需要深挖某类控件或布局时回到 egui_demo_lib/src/demo/ 查找对应 demo 页源码并结合 crates/egui/src/ 的widgets/、containers/源码理解实现细节。小结examples/目录是 egui 官方维护的可运行文档它用一个统一入口eframe 窗口 众多主题化示例覆盖了从最小可运行程序到窗口定制、字体替换、文件拖放、GPU 3D 渲染、多视口、外部事件循环与 Android 部署的完整实践路径。阅读时记住 README 的两条准则——main 分支示例对应最新开发版 API、按需切换到对应版本 tag——再结合每个示例目录内的 README 与截图即可高效定位并复用你需要的参考实现快速搭建自己的 egui 应用。【免费下载链接】eguiegui: an easy-to-use immediate mode GUI in Rust that runs on both web and native项目地址: https://gitcode.com/GitHub_Trending/eg/egui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价