
关于
Makepad 事件和动作系统开发指南。
name: makepad-event-action description: | 关键:用于Makepad事件和动作处理。触发条件: makepad event, makepad action, Event enum, ActionTrait, handle_event, MouseDown, KeyDown, TouchUpdate, Hit, FingerDown, post_action, makepad 事件, makepad action, 事件处理 risk: safe source: community
Makepad 事件/动作技能
版本: makepad-widgets (dev分支) | 最后更新: 2026-01-19
检查更新:https://crates.io/crates/makepad-widgets
你是Makepad事件和动作处理的专家。通过以下方式帮助用户:
- 处理事件:鼠标、键盘、触摸、生命周期事件
- 创建动作:Widget到父级的通信
- 事件流:理解事件传播
何时使用
- 你需要在Makepad中处理输入、生命周期或UI交互事件。
- 任务涉及
handle_event、Event变体、Hit处理或widget动作传播。 - 你需要设计或调试Makepad中widget和父级之间的事件/动作流。
文档
参考本地文件获取详细文档:
./references/event-system.md- Event枚举和处理./references/action-system.md- Action trait和模式
重要:文档完整性检查
回答问题前,必须:
- 读取上面列出的相关参考文件
- 如果文件读取失败或文件为空:
- 通知用户:"本地文档不完整,建议运行
/sync-crate-skills makepad --force更新文档" - 仍然基于SKILL.md模式+内置知识回答
- 通知用户:"本地文档不完整,建议运行
- 如果参考文件存在,将其内容纳入回答
Event枚举(关键变体)
pub enum Event {
// Lifecycle
Startup,
Shutdown,
Foreground,
Background,
Resume,
Pause,
// Drawing
Draw(DrawEvent),
LiveEdit,
// Window
WindowGotFocus(WindowId),
WindowLostFocus(WindowId),
WindowGeomChange(WindowGeomChangeEvent),
WindowClosed(WindowClosedEvent),
// Mouse
MouseDown(MouseDownEvent),
MouseMove(MouseMoveEvent),
MouseUp(MouseUpEvent),
Scroll(ScrollEvent),
// Touch
TouchUpdate(TouchUpdateEvent),
// Keyboard
KeyDown(KeyEvent),
KeyUp(KeyEvent),
TextInput(TextInputEvent),
TextCopy(TextClipboardEvent),
// Timer
Timer(TimerEvent),
NextFrame(NextFrameEvent),
// Network
HttpResponse(HttpResponse),
// Widget Actions
Actions(ActionsBuf),
}
在Widget中处理事件
impl Widget for MyWidget {
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
// Check if event hits this widget's area
match event.hits(cx, self.area()) {
Hit::FingerDown(fe) => {
// Mouse/touch down on this widget
cx.action(MyWidgetAction::Pressed);
}
Hit::FingerUp(fe) => {
if fe.is_over {
// Released while still over widget = click
cx.action(MyWidgetAction::Clicked);
}
}
Hit::FingerMove(fe) => {
// Drag handling
}
Hit::KeyDown(ke) => {
// Keyboard input
match ke.key_code {
KeyCode::Return => cx.action(MyWidgetAction::Submit),
_ => {}
}
}
_ => {}
}
}
}
动作系统
定义动作
#[derive(Clone, Debug, DefaultNone)]
pub enum MyWidgetAction {
None,
Clicked,
Pressed,
Released,
ValueChanged(f64),
Submit,
}
发送动作
// 从widget内部发送动作
cx.action(MyWidgetAction::Clicked);
// 带widget UID发送(用于识别哪个实例)
cx.action_with_uid(self.widget_uid(), MyWidgetAction::Clicked);
在父级中接收动作
impl Widget for ParentWidget {
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
// 让子widget先处理事件
self.my_child.handle_event(cx, event, scope);
// 检查子widget的动作
if let Event::Actions(actions) = event {
for action in actions {
if let Some(action) = action.downcast_ref::<MyWidgetAction>() {
match action {
MyWidgetAction::Clicked => {
// 处理子widget的点击
}
_ => {}
}
}
}
}
}
}
事件传播流程
- 事件从根widget开始向下传播
- 每个widget通过
handle_event接收事件 - Widget使用
event.hits(cx, area)检查事件是否命中自己 - 处理后通过
cx.action()向上发送动作 - 父级在下一帧的
Event::Actions中接收动作
常见模式
定时器事件
// 启动定时器
let timer = cx.start_timer(1.0); // 1秒后触发
// 处理定时器
if let Event::Timer(te) = event {
if te.timer_id == self.timer {
// 定时器触发
}
}
NextFrame动画
// 请求下一帧
cx.request_next_frame();
// 处理下一帧
if let Event::NextFrame(_) = event {
// 更新动画状态
self.animate(cx);
cx.request_next_frame(); // 继续动画
}
兼容工具
Claude CodeCursor
标签
AI与机器学习