Makepad UI 代码怎么读:别被语法吓住
2026/6/8 15:22:26 网站建设 项目流程

前三期聊了选型、对比、跑 demo。如果你跟着上一期把counter跑起来了,窗口弹出来那一瞬间应该还挺爽的。

然后你打开src/main.rs,往下翻了几行。

不是熟悉的 Rust 结构体,不是fn main(),而是一堆看起来像 CSS 又像 JSON、但两边都不像的东西。

我当时是半夜看的,盯着屏幕愣了大概两分钟。

然后去搜教程。更懵了。有的文章在讲live_design!,有的在讲script_mod!,还有在讲 Splash 的。我花了一整个晚上才搞明白它们之间的关系。

这一期就是想帮你省掉那个晚上。

先交底:这篇不是 Splash 语法大全,也不是官方文档翻译。它就是一份"第一次打开 Makepad 代码时,先看懂哪几块就够了"的导航。

1. 先别读代码,先搞清楚一个时间线

很多人卡在这一步,问题不在代码本身,而在于看了不同时代的资料。

Makepad 的 UI 描述方式经历过一次比较大的转向:

  • 老版本:用live_design!宏写 UI,语法混在 Rust 宏里
  • 当前版本(Makepad 2.0 / dev 分支):用script_mod!+ Splash,UI 描述变成了一套独立的 DSL

这不是"旧语法换了几个关键字"那种小改。是整个 UI 描述层的组织思路变了。

所以你搜到 2023 年的教程全是live_design! { ... },而官方dev分支打开全是script_mod!和 Splash。你没看错,它们就是同一个框架在两个时间点的样子。

这个时间差不说清楚,新手大概率会越搜越乱。

截至2026 年 6 月,官方dev分支的示例已经全面偏向script_mod!/ Splash。这一篇也按新写法来。

2. 第一层:UI 声明 —— 界面长什么样

先解决最让人困惑的问题:在 Makepad 里,一个界面到底是怎么被"描述"出来的。

2.1 一个最小示例

以官方counter为参考,简化后大概长这样:

script_mod!(modmy_app{main_window:=Window{window.inner_size:vec2(420,220)body+:{View{width:Fill,height:Fill,flow:Down,align:CenterLabel{text:"Count: 0"}Button{text:"Increment"}}}}});

我第一次看到这段代码,脑子里有两个问号:

  1. script_mod!是啥?这算 Rust 代码吗?
  2. main_window := Window { ... },这:=又是什么语法?

2.2 先别管script_mod!

script_mod!是个宏,编译时 Makepad 会把里面的 DSL 展开成框架能理解的东西。

第一次读,别追宏展开。追了就出不来了。

你只需要先抓住一件事:这段代码定义了一个窗口,窗口里有一个垂直排列的视图,视图里放了一个标签和一个按钮。够了。

2.3:=+:记两个词就行

这两个符号是 Makepad DSL 里出现频率最高的,也是新手最容易懵的:

  • main_window := Window { ... }:声明一个叫main_window的东西,类型是Window
  • body +: { ... }:往body里面追加内容

粗暴理解:

  • :=→ “我声明一个”
  • +:→ “往里面塞”

不严谨。但够用。第一遍读不卡住就是胜利。

2.4 先认控件名,别的往后放

读 Makepad UI 代码最省力的办法:

先找你认识的单词,忽略不认识的语法。

上面那段代码,你盯住这四个词就行:

  • Window— 窗口
  • View— 容器
  • Label— 文本
  • Button— 按钮

这四个认出来,界面的骨架已经在你脑子里了。vec2(420, 220)FillDown第二轮再看,别急。

3. 第二层:布局和样式 —— 东西怎么摆

知道"有什么"了,下一步:这些东西为什么摆在那个位置。

3.1 flow 管方向

flow是 Makepad 里用得最多的布局属性。没有之一。

View { flow: Down, // 从上往下排 // flow: Right, // 从左往右排 }

Down是垂直,Right是水平。和 CSS 的flex-direction: column / row一个意思,只是名字更短。

3.2 align 管对齐

View { flow: Down, align: Center, }

align管的是子元素在排列方向上的对齐。CenterStartEnd,三个值够用了。

3.3 width / height 管尺寸

View { width: Fill, // 撑满 height: 200, // 固定 200 } Button { width: Fit, // 自适应内容 }

Fill撑满,Fit自适应,具体数字就是固定尺寸。flow+align+width/height,三个属性组合起来,常见布局基本都能出来。

3.4 样式直接写在控件上

这一点和 CSS 差别很大。Makepad 没有单独的样式表,颜色、字体、间距全写在控件上:

Label { text: "Hello" draw_text: { color: #333333, font_size: 16.0 } }

我第一次看到这种写法,第一反应是"这也太不分离了吧"。但用了两天之后发现,看一个控件就能看到它的全部外观,不用去另一个文件翻 class。说实话,小项目里挺爽的。

4. 第三层:事件和逻辑 —— 点了为什么有反应

界面能看了,布局能摆了。最后一步:点了按钮,为什么会有反应。

4.1 UI 描述和 Rust 逻辑在同一个script_mod!里,但角色分开

script_mod!(modmy_app{// 第一部分:UI 描述(DSL)main_window:=Window{...}// 第二部分:Rust 逻辑#[run]fnmain()->Result<(),String>{// 初始化}#[event]fnhandle_button_click(&mutself,cx:&mutCx,actions:&Actions){// 事件处理}});

UI 描述只管"长什么样",Rust 逻辑管"点完发生什么"。它们写在一个宏里,但分工很明确。

4.2 按钮点击是怎么接上的

以 counter 的点击为例,简化后大概是这样:

// UI 侧:给按钮一个 idButton{id:increment_button,text:"Increment"}// Rust 侧:通过 id 找到按钮,判断是否被点击ifself.ui.button(cx,ids!(increment_button)).clicked(actions){self.count+=1;self.ui.label(cx,ids!(count_label)).set_text(cx,&format!("Count: {}",self.count));self.ui.redraw(cx);}

整个连接靠的就是id

UI 里给控件起个名字(id: increment_button),Rust 里通过同一个名字找到它(ids!(increment_button)),然后判断事件、更新状态、触发重绘。

所以我读 Makepad 代码有个习惯:先扫一遍 UI 描述,把所有id圈出来。这些id就是 UI 和逻辑之间的接头暗号,找到它们,后面的关系网就清楚了。

4.3 状态放哪

Makepad 里状态直接挂在script_mod!模块里:

script_mod!(modmy_app{count:i32=0,name:String=String::new(),main_window:=Window{...}#[event]fnhandle_click(&mutself,cx:&mutCx,actions:&Actions){// self.count, self.name 直接用}});

不需要单独的 store,不需要 context。字段就挂在模块上,self.xxx直接访问。中小型应用里这个模型用起来很快。

5. 一条偷懒的阅读顺序

如果现在你打开一个 Makepad 示例,不知道从哪开始看,按这个顺序来:

  1. 先找main_window— 界面入口,往下追
  2. 认控件名WindowViewLabelButton……先在脑子里画个树
  3. flowalign— 搞清楚东西为什么在这个位置
  4. 找所有id— 有id的控件,说明 Rust 那边会用到它
  5. 顺着id跳到 Rust— 看事件处理、状态更新

这个顺序走一遍,大部分示例就不会再给人"一堆符号看不懂"的感觉了。

6. 我踩过的两个坑

6.1 拿 CSS 心智硬套

Makepad 的 DSL 和 CSS 有几个词长得像(widthalign),但布局模型完全不是 Flexbox。

  • 没有display: flexflow就是排列方式
  • 没有margin/padding的完整对应
  • 样式不级联,父元素不影响子元素

我当时卡在这上面至少两个小时,一直在找"Makepad 的 padding 怎么写"。后来发现有些东西它就是没有。接受"这是一套新东西"比纠结"为什么和 CSS 不一样"快得多。

6.2 一上来就想搞懂宏展开

script_mod!展开之后代码量很大,充满框架内部细节。

第一次读,把它当黑盒。先理解里面的 DSL 结构和 Rust 逻辑怎么组织。等你整个框架有感觉了,回头看宏展开,那个时机才对。

7. 和上一期的关系

从第三期直接过来的话:

  • 第三期:把窗口跑起来,按钮能点
  • 这一期:看懂这些按钮和文字是怎么被定义、怎么被摆放、怎么连上逻辑的

两期合在一起,你就能从"能跑"走到"能读"。

总结

这一期其实就一件事:帮你建立 Makepad UI 代码的阅读框架。

认控件名 → 看 flow/align → 顺 id 找逻辑。这个顺序抓住,大部分代码就不会再让你愣在那了。

下一期拆事件处理、状态管理和组件通信。从"能看的界面"到"能交互的应用"。

你第一次打开 Makepad 代码,卡在哪一步?评论区聊聊。我猜很多人的答案都差不多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询