| name | gpui-app |
| description | 从零搭建 gpui / gpui-component 桌面应用的起步模板。涵盖 Cargo.toml git 依赖(gpui + gpui_platform + gpui-component)、main.rs 入口(application().run / open_window / Root)、资产与图标注册、WindowOptions、退出与激活。创建新 gpui 项目、初始化工程、写 main.rs 或配置依赖时使用。 |
gpui 应用起步模板
以下内容按 zed 主干 gpui(0.2.x)与 gpui-component 0.5.x 源码核实(zed crates/gpui/examples/hello_world.rs、gpui-component examples/hello_world)。
1. Cargo.toml
gpui 不发布 crates.io 正式版,统一用 git 依赖;gpui_platform 必须一并引入(平台后端 + 入口函数):
[package]
name = "my-app"
version = "0.1.0"
edition = "2024"
[dependencies]
gpui = { git = "https://github.com/zed-industries/zed" }
gpui_platform = { git = "https://github.com/zed-industries/zed", features = ["font-kit"] }
gpui-component = { git = "https://github.com/longbridge/gpui-component" }
gpui-component-assets = { git = "https://github.com/longbridge/gpui-component" }
[profile.dev.package]
gpui = { opt-level = 3 }
gpui_platform = { opt-level = 3 }
taffy = { opt-level = 3 }
resvg = { opt-level = 3 }
rustybuzz = { opt-level = 3 }
ttf-parser = { opt-level = 3 }
注意:crate 名 gpui-component,导入名 gpui_component。若与 gpui-component 同用,两处 git 的 zed 版本由 Cargo 统一解析;编译报 gpui 版本冲突时,以 gpui-component 锁定的 zed rev 为准。
2. 纯 gpui 最小应用
use gpui::{
App, Bounds, Context, SharedString, Window, WindowBounds, WindowOptions,
div, prelude::*, px, rgb, size,
};
use gpui_platform::application;
struct HelloWorld {
text: SharedString,
}
impl Render for HelloWorld {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div()
.flex()
.flex_col()
.gap_2()
.size_full()
.justify_center()
.items_center()
.bg(rgb(0x2e7d32))
.text_color(rgb(0xffffff))
.child(format!("Hello, {}!", self.text))
}
}
fn main() {
application().run(|cx: &mut App| {
let bounds = Bounds::centered(None, size((.), (.)), cx);
cx.(
WindowOptions {
window_bounds: (WindowBounds::(bounds)),
..::()
},
|_window, cx| cx.(|_| HelloWorld { text: .() }),
)
.();
cx.();
});
}
要点:
use gpui::prelude::*; 必带,否则 .flex()/.child()/Render 等 trait 方法全部找不到(E0599)。
open_window 构建闭包签名 (&mut Window, &mut App) -> Entity<V>,必须返回 cx.new(…)。
- 入口是
gpui_platform::application();Application::new() 已不存在。
3. gpui-component 应用(带 Root)
use gpui::{App, Window, WindowOptions, prelude::*};
use gpui_component::{ActiveTheme as _, Root, button::Button, h_flex};
struct Example;
impl Render for Example {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
h_flex()
.size_full()
.justify_center()
.items_center()
.bg(cx.theme().background)
.child(Button::new("hi").primary().label("Hello"))
}
}
fn main() {
gpui_platform::application()
.with_assets(gpui_component_assets::Assets)
.run(move |cx| {
gpui_component::init(cx);
cx.spawn(async move |cx| {
cx.open_window(WindowOptions::(), |window, cx| {
= cx.(|_| Example);
cx.(|cx| Root::(view, window, cx).(cx.().background))
})
.();
})
.();
});
}
三条硬性顺序:init(cx) 最先 → 窗口首层 Root → 主题访问 use gpui_component::ActiveTheme as _; 后 cx.theme()。
4. 常用 WindowOptions 字段
window_bounds: Option<WindowBounds>(Windowed/Maximized/Fullscreen)、titlebar: Option<TitlebarOptions>、focus、show、kind、is_movable、is_resizable、is_minimizable、window_background、app_id、window_min_size、window_decorations、icon。无 WindowBounds::Fixed。
5. 退出与窗口关闭
窗口关闭默认不退出应用,需要"最后窗口关闭即退出"时(已对照 examples/on_window_close_quit.rs):
cx.on_window_closed(|cx, _window_id| {
if cx.windows().is_empty() {
cx.quit();
}
})
.detach();
相关:代码里主动关窗用 window.remove_window();绑定快捷键 cx.bind_keys([KeyBinding::new("cmd-w", CloseWindow, None)]) 配合 actions!(example, [CloseWindow]) 与元素上的 .on_action(|_: &CloseWindow, window, _| window.remove_window())。
6. 下一步
- 布局/样式:
skill://gpui/references/layout-style.md
- 实体与状态:
skill://gpui/references/entity.md
- 动作与快捷键:
skill://gpui/references/action.md
- 组件目录:
skill://gpui-component
- 新旧 API 对照:
skill://gpui-migration