emilk/egui
GitHub: emilk/egui
egui 是一个用 Rust 实现的轻量级即时模式 GUI 库,解决跨平台界面构建的复杂度问题。
Stars: 28740 | Forks: 2005
# 🖌 egui: 一个纯 Rust 实现的易用 GUI
[
](https://github.com/emilk/egui)
[](https://crates.io/crates/egui)
[](https://docs.rs/egui)
[](https://github.com/rust-secure-code/safety-dance/)
[](https://github.com/emilk/egui/actions/workflows/rust.yml)
[](https://github.com/emilk/egui/blob/main/LICENSE-MIT)
[](https://github.com/emilk/egui/blob/main/LICENSE-APACHE)
[](https://discord.gg/JFcEma9bJq)
egui(发音为 "e-gooey")是一个简单、快速且高度便携的即时模式 GUI 库,适用于 Rust。egui 可在 Web 上运行,原生运行,也可在[你喜爱的游戏引擎](#integrations)中运行。 egui 旨在成为最容易使用的 Rust GUI 库,以及在 Rust 中制作网页应用的最简单方式。 egui 可在任何可以绘制纹理三角形的地方使用,这意味着你可以轻松将其集成到你选择的游戏引擎中。 [`eframe`](https://github.com/emilk/egui/tree/main/crates/eframe) 是官方的 egui 框架,支持为 Web、Linux、Mac、Windows 和 Android 编写应用。 ## 示例 ``` ui.heading("My egui Application"); ui.horizontal(|ui| { ui.label("Your name: "); ui.text_edit_singleline(&mut name); }); 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}")); ui.image(egui::include_image!("ferris.png")); ```
## 目录:
* [示例](#example)
* [快速开始](#quick-start)
* [演示](#demo)
* [目标](#goals)
* [状态 / 特性](#state)
* [依赖](#dependencies)
* [适用对象](#who-is-egui-for)
* [集成](#integrations)
* [为何采用即时模式](#why-immediate-mode)
* [常见问题](#faq)
* [其他](#other)
* [致谢](#credits)
([egui 的中文翻译文档 / chinese translation](https://github.com/Re-Ch-Love/egui-doc-cn/blob/main/README_zh-hans.md))
## 快速开始
[simple examples](https://github.com/emilk/egui/blob/main/examples/) 中有一些简单示例。如果你想编写一个网页应用,请前往 并按照说明操作。官方文档位于 。更多灵感和示例请查看 [egui 网页演示](https://www.egui.rs/#demo) 并跟随其源码中的链接。
如果你想将 egui 集成到现有引擎中,请前往 [集成](#integrations) 章节。
如果你有问题,请使用 [GitHub Discussions](https://github.com/emilk/egui/discussions)。此外还有 [egui Discord 服务器](https://discord.gg/JFcEma9bJq)。如果你想为 egui 贡献,请阅读 [贡献指南](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)。
## 演示
[点击运行 egui 网页演示](https://www.egui.rs/#demo)(支持任何具备 Wasm 和 WebGL 支持的浏览器)。使用 [`eframe`](https://github.com/emilk/egui/tree/main/crates/eframe)。
要在本地测试演示应用,请运行 `cargo run --release -p egui_demo_app`。
原生后端是 [`egui-wgpu`](https://github.com/emilk/egui/tree/main/crates/egui-wgpu)(使用 [`wgpu`](https://crates.io/crates/wgpu)),在 Mac 和 Windows 上开箱即用,但在 Linux 上你需要先运行:
`sudo apt-get install -y libclang-dev libgtk-3-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev libssl-dev`
在 Fedora Rawhide 上你需要运行:
`dnf install clang clang-devel clang-tools-extra libxkbcommon-devel pkg-config openssl-devel libxcb-devel gtk3-devel atk fontconfig-devel`
**注意**:这只适用于演示应用——egui 本身完全与平台无关!
## 目标
* 最易使用的 GUI 库
* 响应式:在调试构建中目标 60 Hz
* 友好:难以犯错,且不应 panic
* 可移植:同一代码可在 Web 和原生应用中运行
* 易于集成到任何环境
* 用于自定义绘图的简单 2D 图形 API([`epaint`](https://docs.rs/epaint))
* 纯即时模式:无需回调
* 可扩展:[轻松为 egui 编写自己的控件](https://github.com/emilk/egui/blob/main/crates/egui_demo_lib/src/demo/toggle_switch.rs)
* 模块化:应能使用 egui 的小部分并以新方式组合
* 安全:egui 中没有 `unsafe` 代码
* 依赖极少
egui *不是* 一个框架。egui 是一个你调用的库,而不是你为之编程的环境。
**注意**:egui 尚未声称实现了所有这些目标!egui 仍在开发中。
### 非目标
* 成为最强大的 GUI 库
* 原生外观的界面
## 状态
egui 处于积极开发阶段。它能很好地完成其设计功能,但缺少许多特性,且接口仍在变动中。新版本会有破坏性变更。
尽管如此,egui 仍可用于创建外观专业的应用,例如 [Rerun Viewer](https://app.rerun.io/)。
### 特性
* 控件:标签、文本按钮、超链接、复选框、单选按钮、滑块、可拖动数值、文本编辑、颜色选择器、微调器
* 图像
* 布局:水平、垂直、列、自动换行
* 文本编辑:多行、复制/粘贴、撤销、Emoji 支持
* 窗口:移动、调整大小、命名、最小化和关闭。自动调整大小和定位。
* 区域:调整大小、垂直滚动、折叠标题(分区)、面板
* 渲染:抗锯齿渲染线条、圆形、文本和凸多边形
* 悬停提示
* 通过 [AccessKit](https://accesskit.dev/) 的可访问性支持
* 标签文本选择
* 等等!
查看 [第三方 egui crates 维基](https://github.com/emilk/egui/wiki/3rd-party-egui-crates) 获取更多
控件和功能,由社区维护。
浅色主题:
## 依赖
`egui` 的默认依赖集很小。
重量级依赖被保留在 `egui` 之外,即使作为可选项。
`egui` 中的所有代码都适用于 Wasm(即使在浏览器之外)。
要向 `egui` 加载图像,可以使用官方 [`egui_extras`](https://github.com/emilk/egui/tree/main/crates/egui_extras) crate。
另一方面,[`eframe`](https://github.com/emilk/egui/tree/main/crates/eframe) 有大量依赖,包括 [`winit`](https://crates.io/crates/winit)、[`image`](https://crates.io/crates/image)、图形 crate、剪贴板 crate 等,
## 适用对象
egui 适用于当你想要一种简单的方式来创建 GUI,或想为游戏引擎添加 GUI 时。
如果你不使用 Rust,egui 不适合你。如果你想要一个原生外观的 GUI,egui 不适合你。如果你想要一个升级后不会破坏的东西,egui 目前也不适合你。
但如果你正在 Rust 中编写交互式内容并需要一个简单的 GUI,egui 可能适合你。
## 集成
egui 设计为易于集成到你正在任何现有游戏引擎或平台中。
egui 本身不了解它运行在哪个操作系统,也不了解如何将内容渲染到屏幕上——这是*集成*或*后端*的工作。
一个集成需要在每一帧执行以下操作:
* **输入**:收集输入(鼠标、触摸、键盘、屏幕大小等)并提供给 egui
* 调用应用程序 GUI 代码
* **输出**:处理 egui 输出(光标变化、粘贴、纹理分配、…)
* **绘制**:渲染 egui 生成的网格三角形(参见 [OpenGL 示例](https://github.com/emilk/egui/blob/main/crates/egui_glow/src/painter.rs))
### 官方集成
以下是官方 egui 集成:
* [`eframe`](https://github.com/emilk/egui/tree/main/crates/eframe) 用于将同一应用编译为 Web/Wasm 和桌面/原生。使用 `egui-winit` 和 `egui_glow` 或 `egui-wgpu`
* [`egui_glow`](https://github.com/emilk/egui/tree/main/crates/egui_glow) 用于使用 [glow](https://github.com/grovesNL/glow) 在原生和 Web 上渲染 egui,并用于制作原生应用
* [`egui-wgpu`](https://github.com/emilk/egui/tree/main/crates/egui-wgpu) 用于 [wgpu](https://crates.io/crates/wgpu)(WebGPU API)
* [`egui-winit`](https://github.com/emilk/egui/tree/main/crates/egui-winit) 用于与 [winit](https://github.com/rust-windowing/winit) 集成
### 第三方集成
在维基中查看 [第三方集成](https://github.com/emilk/egui/wiki/3rd-party-integrations)
和 [egui crates](https://github.com/emilk/egui/wiki/3rd-party-egui-crates)。
### 编写你自己的 egui 集成
找不到你正在使用的项目的集成?创建一个,很简单!
请参阅 。
## 为何采用即时模式
`egui` 是一个[即时模式 GUI 库](https://en.wikipedia.org/wiki/Immediate_mode_GUI),而非*保留模式* GUI 库。保留模式与即时模式的区别最好通过按钮示例来说明:在保留模式 GUI 中,你创建一个按钮,将其添加到 UI 中并安装一个点击处理程序(回调)。按钮被保留在 UI 中,要更改其文本需要保存对其的某种引用。相比之下,在即时模式中,你显示按钮并立即与之交互,每帧都这样做(例如每秒 60 次)。这意味着不需要任何点击处理程序,也不需要保存其引用。在 `egui` 中这样写:`if ui.button("Save file").clicked() { save(file); }`。
即时模式的更详细描述可以在[`egui` 文档](https://docs.rs/egui/latest/egui/#understanding-immediate-mode)中找到。
两者系统各有优缺点。
简而言之:即时模式 GUI 库更易用,但功能较弱。
### 即时模式的优势
#### 易用性
即时模式的主要优势在于应用程序代码变得极其简单:
* 你永远不需要任何点击处理程序和回调,不会扰乱代码流程。
* 你不必担心悬停的回调调用了已被释放的对象。
* 你的 GUI 代码可以轻松位于一个简单函数中(无需为 UI 创建对象)。
* 你不必担心应用程序状态与 GUI 状态不同步(即 GUI 显示的内容过时),因为 GUI 不存储任何状态——它立即显示最新状态。
换句话说,大量代码、复杂性和错误被消除,你可以将时间集中在比编写 GUI 代码更有趣的事情上。
### 即时模式的劣势
#### 布局
即时模式的主要劣势在于布局更困难。假设你想在屏幕中央显示一个小对话框。为了正确放置窗口,GUI 库必须首先知道它的大小。要知道窗口大小,GUI 库必须先布局窗口内容。在保留模式中这很简单:GUI 库执行窗口布局,定位窗口,然后检查交互(“OK 按钮是否被点击?”)。
在即时模式中你会陷入悖论:要了解窗口大小,我们必须执行布局,但布局代码也检查交互(“OK 按钮是否被点击?”),因此它需要在显示窗口内容*之前*知道窗口位置。这意味着我们必须*在*知道窗口大小*之前*决定显示位置!
这是即时模式 GUI 的根本局限,任何解决方案都有其缺点。
一种变通方法是存储大小并在下一帧使用它。这会导致布局正确时有一帧延迟,首次显示内容时可能出现闪烁。`egui` 对窗口和网格布局等某些内容会这样做。
“首帧抖动”可以通过额外的*遍历*来掩盖,egui 通过 `Context::request_discard` 支持此功能。
这种方法的缺点是增加了第二次遍历的 CPU 开销,因此 egui 仅在极少数情况下这样做(大多数帧是单次遍历)。
对于“原子”控件(例如按钮),`egui` 在显示之前就知道其大小,因此无需特殊变通方法即可在 `egui` 中居中按钮、标签等。
有关更多信息,请参阅[此问题](https://github.com/emilk/egui/issues/4378)。
#### CPU 使用率
由于即时模式 GUI 每帧都会执行完整布局,布局代码必须快速。如果你有一个非常复杂的 GUI,这可能会消耗 CPU。特别是拥有一个包含大量内容的滚动区域(具有很长的回滚)会很慢,因为内容需要每帧布局。
如果你在设计 GUI 时牢记这一点,并避免巨大的滚动区域(或仅布局可见部分),性能影响通常很小。对于大多数情况,你可以期望 `egui` 每帧占用 1-2 毫秒,但 `egui` 仍有大量优化空间(目前这不是我的重点)。`egui` 仅在有交互(例如鼠标移动)或动画时才重绘,因此如果你的应用处于空闲状态,不会浪费 CPU。
如果你的 GUI 高度交互,那么即时模式实际上可能比保留模式更具性能优势。尝试调整任何网页窗口大小,你会发现浏览器在布局和消耗大量 CPU 方面非常慢。相比之下,在 `egui` 中调整窗口大小时,你会获得流畅的 60 FPS 而没有额外的 CPU 开销。
#### ID
有些 GUI 状态你希望 GUI 库保留,即使在像 `egui` 这样的即时模式库中也是如此。这包括窗口的位置和大小,以及用户在某个 UI 中的滚动距离。在这种情况下,你需要为 `egui` 提供一个唯一标识符的种子(在父 UI 范围内唯一)。例如:默认情况下 `egui` 使用窗口标题作为存储窗口位置的唯一 ID。如果你想有两个同名窗口(或一个动态命名的窗口),你必须提供其他 ID 源给 `egui`(某个唯一整数或字符串)。
`egui` 还需要跟踪哪个控件正在被交互(例如哪个滑块正在被拖动)。`egui` 也为此使用唯一 ID,但这些 ID 是自动生成的,因此用户无需担心。特别地,拥有同名两个按钮不是问题(这与 [`Dear ImGui`](https://github.com/ocornut/imgui) 不同)。
总体而言,ID 处理是一个罕见的轻微不便,并非重大劣势。
## 常见问题
同时参见 [GitHub Discussions](https://github.com/emilk/egui/discussions/categories/q-a)。
### 我可以在 `egui` 中使用非拉丁字符吗?
可以!但你需要使用 [`Context::set_fonts`](https://docs.rs/egui/latest/egui/struct.Context.html#method.set_fonts) 安装自己的字体(`.ttf` 或 `.otf`)。
### 我可以自定义 `egui` 的外观吗?
可以!你可以使用 `Context::set_style` 自定义所有内容的颜色、间距、字体和大小。
这还不足以媲美 CSS,但[正在改进](https://github.com/emilk/egui/issues/3284)。
这是一个示例(来自 https://github.com/a-liashenko/TinyPomodoro):
### 我如何在 `async` 中使用 `egui`?
如果在 GUI 代码中使用 `.await`,UI 会冻结,这会严重影响用户体验。相反,请保持 GUI 线程非阻塞,并使用以下方式与任何并发任务(async 任务或其他线程)进行通信:
* 通道(例如 [`std::sync::mpsc::channel`](https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html))。确保使用 [`try_recv`](https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver.html#method.try_recv),以免阻塞 GUI 线程!
* `Arc>`(后台线程设置值;GUI 线程读取)
* [`poll_promise::Promise`](https://docs.rs/poll-promise)
* [`eventuals::Eventual`](https://docs.rs/eventuals/latest/eventuals/struct.Eventual.html)
* [`tokio::sync::watch::channel`](https://docs.rs/tokio/latest/tokio/sync/watch/fn.channel.html)
### 如何创建文件对话框?
异步版本的 [rfd](https://docs.rs/rfd/latest/rfd/) 支持原生和 Wasm。请参见示例应用 [here](https://github.com/woelper/egui_pick_file),其中也提供了[演示](https://github.com/woelper/egui_pick_file/blob/main/README.md#github-pages)。
### 无障碍访问(如屏幕阅读器)如何?
egui 包含对 [AccessKit](https://accesskit.dev/) 的可选支持,目前在 Windows 和 macOS 上实现了原生无障碍 API。此功能在 eframe 中默认启用。对于 Access 尚未支持的平台(包括 Web),有一个实验性的内置屏幕阅读器;在[网页演示](https://www.egui.rs/#demo)中,你可以在“后端”标签中启用它。
关于 egui 中无障碍访问的原始讨论请参见 。现在 AccessKit 支持已合并,为未来的无障碍工作奠定了坚实基础,请针对具体无障碍问题打开新 issue。
### [egui](https://docs.rs/egui) 与 [eframe](https://github.com/emilk/egui/tree/main/crates/eframe) 的区别是什么?
`egui` 是一个用于布局和交互按钮、滑块等的 2D 用户界面库。
`egui` 不知道它是在 Web 上运行还是原生运行,也不知道如何收集输入或在屏幕上显示内容。
这正是*集成*或*后端*的工作。
通常从游戏引擎(使用例如 [`bevy_egui`](https://docs.rs/bevy_egui))中使用 `egui`,
但你也可以使用 `eframe` 单独使用 `egui`。`eframe` 提供了 Web 和原生的集成,并处理输入和渲染。
`eframe` 中的“帧”既指你的 egui 应用所在的帧,也指“框架”(`eframe` 是一个框架,`egui` 是一个库)。
### 如何在 egui 区域中渲染 3D 内容?
有多种方式可以将 egui 与 3D 结合。最简单的方法是使用 3D 库并将 egui 放在 3D 视图之上。例如 [`bevy_egui`](https://github.com/mvlabat/bevy_egui) 或 [`three-d`](https://github.com/asny/three-d)。
如果你想将 3D 内容嵌入到 egui 视图中,有两种选择:
#### `Shape::Callback`
示例:
*
`Shape::Callback` 会在 egui 绘制时调用你的代码,以使用任何后台渲染上下文显示内容。使用 [`eframe`](https://github.com/emilk/egui/tree/main/crates/eframe) 时这将是 [`glow`](https://github.com/grovesNL/glow)。其他集成会提供其他渲染上下文(如果支持 `Shape::Callback`)。
#### 渲染到纹理
你也可以将 3D 场景渲染到纹理,并使用 [`ui.image(…)`](https://docs.rs/egui/latest/egui/struct.Ui.html#method.image) 显示它。首先需要将原生纹理转换为 [`egui::TextureId`](https://docs.rs/egui/latest/egui/enum.TextureId.html),具体转换方式取决于你使用的集成。
示例:
* 使用 [`egui-miniquad`]( https://github.com/not-fl3/egui-miniquad):https://github.com/not-fl3/egui-miniquad/blob/master/examples/render_to_egui_image.rs
* 使用 [`eframe`](https://github.com/emilk/egui/tree/main/crates/eframe) + [`VTK (C++)`](https://vtk.org/):https://github.com/Gerharddc/vtk-egui-demo
## 其他
### 约定和设计选择
所有坐标均为屏幕空间坐标,(0, 0) 位于左上角。
所有坐标均为逻辑“点”,可能由许多物理像素组成。
所有颜色均为预乘 alpha,除非另有说明。
egui 使用构建器模式来构造控件。例如:`ui.add(Label::new("Hello").text_color(RED));`。我并不特别喜欢构建器模式(它在实现和使用上都相当冗长),但直到 Rust 拥有命名默认参数之前,这是我们能做的最好的选择。为了缓解一些冗长,常见情况有辅助函数,例如 `ui.label("Hello");`。
而不是使用匹配 `begin/end` 风格函数调用(容易出错),egui 更倾向于使用传递给包装函数的 `FnOnce` 闭包。Lambda 有点丑陋,所以我希望找到更好的解决方案。更多讨论请参见 。
egui 为短时间的 `Context` 数据访问使用单个 `RwLock`。这是为了保持实现简单、事务性,并允许用户并行运行 UI 逻辑。egui 不创建互斥锁守卫,而是使用传递给包装函数的闭包,例如 `ctx.input(|i| i.key_down(Key::A))`。这样可以减少用户意外双重锁定 `Context` 的可能性,从而避免死锁。
### 灵感
唯一且绝佳的[即时模式 GUI](https://github.com/ocornut/imgui) 是 C++ 的 Dear ImGui,它支持许多后端。该库彻底改变了我对 GUI 代码的思考方式,并将 GUI 编程从一件讨厌的事情变成我现在享受的事情。
### 名称
该库和项目的名称是 "egui",发音为 "e-gooey"。请不要写成 "EGUI"。
该库最初名为 "Emigui",但在 2020 年更名为 "egui"。
## 致谢
egui 的作者和维护者:Emil Ernerfeldt ([@emilk](https://github.com/emilk))。
重要贡献者:
* [@n2](https://github.com/n2):[移动端网页输入和 IME 支持](https://github.com/emilk/egui/pull/253)
* [@optozorax](https://github.com/optozorax):[任意控件数据存储](https://github.com/emilk/egui/pull/257)
* [@quadruple-output](https://github.com/quadruple-output):[多点触控](https://github.com/emilk/egui/pull/306)
* [@EmbersArc](https://github.com/EmbersArc):[绘图](https://github.com/emilk/egui/pulls?q=+is%3Apr+author%3AEmbersArc)
* [@AsmPrgmC3](https://github.com/AsmPrgmC3):[适用于网页的 sRGBA 正确混合](https://github.com/emilk/egui/pull/650)
* [@AlexApps99](https://github.com/emilk/egui/pull/685):[`egui_glow`](https://github.com/emilk/egui/pull/685)
* [@mankinskin](https://github.com/mankinskin):[上下文菜单](https://github.com/emilk/egui/pull/543)
* [@KentaTheBugMaker](https://github.com/KentaTheBugMaker):[将 glow 渲染器移植到网页](https://github.com/emilk/egui/pull/868)
* [@danielkeller](https://github.com/danielkeller):[`Context` 重构](https://github.com/emilk/egui/pull/1050)
* [@MaximOsipenko](https://github.com/MaximOsipenko):[`Context` 锁重构](https://github.com/emilk/egui/pull/2625)
* [@mwcampbell](https://github.com/mwcampbell):[AccessKit](https://github.com/AccessKit/accesskit) [集成](https://github.com/emilk/egui/pull/2294)
* [@hasenbanck](https://github.com/hasenbanck), [@s-nie](https://github.com/s-nie), [@Wumpf](https://github.com/Wumpf):[`egui-wgpu`](https://github.com/emilk/egui/tree/main/crates/egui-wgpu)
* [@jprochazk](https://github.com/jprochazk):[egui 图像 API](https://github.com/emilk/egui/issues/3291)
* 以及其他许多贡献者。
egui 采用 [MIT](LICENSE-MIT) 或 [Apache-2.0](LICENSE-APACHE) 许可。
* 样条曲线展平算法来自 [lyon_geom](https://docs.rs/lyon_geom/latest/lyon_geom/)
默认字体:
* `emoji-icon-font.ttf`: [Copyright (c) 2014 John Slegers](https://github.com/jslegers/emoji-icon-font) , MIT 许可
* `Hack-Regular.ttf`: , [MIT 许可](https://github.com/source-foundry/Hack/blob/master/LICENSE.md)
* `NotoEmoji-Regular.ttf`: [google.com/get/noto](https://google.com/get/noto), [SIL Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL)
* `Ubuntu-Light.ttf` by [Dalton Maag](http://www.daltonmaag.com/): [Ubuntu 字体许可](https://ubuntu.com/legal/font-licence)
egui(发音为 "e-gooey")是一个简单、快速且高度便携的即时模式 GUI 库,适用于 Rust。egui 可在 Web 上运行,原生运行,也可在[你喜爱的游戏引擎](#integrations)中运行。 egui 旨在成为最容易使用的 Rust GUI 库,以及在 Rust 中制作网页应用的最简单方式。 egui 可在任何可以绘制纹理三角形的地方使用,这意味着你可以轻松将其集成到你选择的游戏引擎中。 [`eframe`](https://github.com/emilk/egui/tree/main/crates/eframe) 是官方的 egui 框架,支持为 Web、Linux、Mac、Windows 和 Android 编写应用。 ## 示例 ``` ui.heading("My egui Application"); ui.horizontal(|ui| { ui.label("Your name: "); ui.text_edit_singleline(&mut name); }); 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}")); ui.image(egui::include_image!("ferris.png")); ```
## 目录:
* [示例](#example)
* [快速开始](#quick-start)
* [演示](#demo)
* [目标](#goals)
* [状态 / 特性](#state)
* [依赖](#dependencies)
* [适用对象](#who-is-egui-for)
* [集成](#integrations)
* [为何采用即时模式](#why-immediate-mode)
* [常见问题](#faq)
* [其他](#other)
* [致谢](#credits)
([egui 的中文翻译文档 / chinese translation](https://github.com/Re-Ch-Love/egui-doc-cn/blob/main/README_zh-hans.md))
## 快速开始
[simple examples](https://github.com/emilk/egui/blob/main/examples/) 中有一些简单示例。如果你想编写一个网页应用,请前往
浅色主题:
## 依赖
`egui` 的默认依赖集很小。
重量级依赖被保留在 `egui` 之外,即使作为可选项。
`egui` 中的所有代码都适用于 Wasm(即使在浏览器之外)。
要向 `egui` 加载图像,可以使用官方 [`egui_extras`](https://github.com/emilk/egui/tree/main/crates/egui_extras) crate。
另一方面,[`eframe`](https://github.com/emilk/egui/tree/main/crates/eframe) 有大量依赖,包括 [`winit`](https://crates.io/crates/winit)、[`image`](https://crates.io/crates/image)、图形 crate、剪贴板 crate 等,
## 适用对象
egui 适用于当你想要一种简单的方式来创建 GUI,或想为游戏引擎添加 GUI 时。
如果你不使用 Rust,egui 不适合你。如果你想要一个原生外观的 GUI,egui 不适合你。如果你想要一个升级后不会破坏的东西,egui 目前也不适合你。
但如果你正在 Rust 中编写交互式内容并需要一个简单的 GUI,egui 可能适合你。
## 集成
egui 设计为易于集成到你正在任何现有游戏引擎或平台中。
egui 本身不了解它运行在哪个操作系统,也不了解如何将内容渲染到屏幕上——这是*集成*或*后端*的工作。
一个集成需要在每一帧执行以下操作:
* **输入**:收集输入(鼠标、触摸、键盘、屏幕大小等)并提供给 egui
* 调用应用程序 GUI 代码
* **输出**:处理 egui 输出(光标变化、粘贴、纹理分配、…)
* **绘制**:渲染 egui 生成的网格三角形(参见 [OpenGL 示例](https://github.com/emilk/egui/blob/main/crates/egui_glow/src/painter.rs))
### 官方集成
以下是官方 egui 集成:
* [`eframe`](https://github.com/emilk/egui/tree/main/crates/eframe) 用于将同一应用编译为 Web/Wasm 和桌面/原生。使用 `egui-winit` 和 `egui_glow` 或 `egui-wgpu`
* [`egui_glow`](https://github.com/emilk/egui/tree/main/crates/egui_glow) 用于使用 [glow](https://github.com/grovesNL/glow) 在原生和 Web 上渲染 egui,并用于制作原生应用
* [`egui-wgpu`](https://github.com/emilk/egui/tree/main/crates/egui-wgpu) 用于 [wgpu](https://crates.io/crates/wgpu)(WebGPU API)
* [`egui-winit`](https://github.com/emilk/egui/tree/main/crates/egui-winit) 用于与 [winit](https://github.com/rust-windowing/winit) 集成
### 第三方集成
在维基中查看 [第三方集成](https://github.com/emilk/egui/wiki/3rd-party-integrations)
和 [egui crates](https://github.com/emilk/egui/wiki/3rd-party-egui-crates)。
### 编写你自己的 egui 集成
找不到你正在使用的项目的集成?创建一个,很简单!
请参阅
### 我如何在 `async` 中使用 `egui`?
如果在 GUI 代码中使用 `.await`,UI 会冻结,这会严重影响用户体验。相反,请保持 GUI 线程非阻塞,并使用以下方式与任何并发任务(async 任务或其他线程)进行通信:
* 通道(例如 [`std::sync::mpsc::channel`](https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html))。确保使用 [`try_recv`](https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver.html#method.try_recv),以免阻塞 GUI 线程!
* `Arc标签:AI工具, Apache许可证, eframe, egui, GUI库, IMGUI, Rust, Rust GUI, Web原生, 前端Rust, 即时模式GUI, 可视化界面, 开源, 无安全代码, 桌面应用, 游戏开发, 游戏引擎集成, 用户界面, 立即模式, 纹理三角形, 网络流量审计, 通知系统

