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
做数据可视化时,报表层级一多,手写表格布局的代码就容易失控:列宽怎么分、表头怎么跨组、滚动时哪块固定,全靠你自己拼。egui_extras 里的 TableBuilder 把这部分收编了——声明列、画表头、填数据行,列宽算法和滚动行为都由 Rust 表格组件内部处理。多级表头不需要你额外拼控件,连续两次调用 header 就行。
层级表格的难处,它是怎么分掉的
egui 是即时模式 GUI:每帧根据数据重绘界面,数据变了,下一帧画面自动跟上。你不需要维护"哪个格子高亮、哪一行选中"这类中间状态,行与行的交互状态由库按 id 记账。
列宽是另一块硬骨头。TableBuilder 是声明式 API:你用链式调用声明列宽、表头和内容,具体怎么分空间由库的列宽算法计算——自动撑开、拖动改宽、双击列头自动适配都内置了。
表头行天然画在滚动体上方。body 行数很大时,只有可见行参与当帧布局,官方 demo 里十万行的表格能正常滚动。
实现是纯 Rust 的,不引入重型 UI 框架,跟 eframe 桌面窗口或 Web 端渲染后端都能接,一份表格代码跨平台跑。
📦 最短路径:一个能跑的两级表头
依赖里加一个 crate(需要完整仓库时:git clone https://gitcode.com/GitHub_Trending/eg/egui):
cargo add egui_extras最小可运行的多级表头示例:
egui_extras::TableBuilder::new(ui) .column(egui_extras::Column::initial(120.0)) .column(egui_extras::Column::initial(120.0)) .column(egui_extras::Column::remainder()) .header(22.0, |mut h| { h.col(|ui| ui.strong("产品线")); h.col(|ui| ui.strong("产品")); h.col(|ui| ui.strong("销量")); }) .header(20.0, |mut h| { h.col(|ui| ui.strong("全部")); h.col(|ui| ui.strong("笔记本")); h.col(|ui| ui.strong("月销量 / 增长")); }) .body(|b| { b.row(22.0, |mut r| { r.col(|ui| ui.label("数码")); r.col(|ui| ui.label("ThinkPad X1")); r.col(|ui| ui.label("1,200 / +12%")); }); });TableBuilder声明列宽并管理滚动区域;header画一行固定表头,返回的Table还能继续链一次header,这就是多级表头的全部做法;body闭包里的row.col按列填内容。
📊 拿它做一张电商月报
需求:产品按"产品线"分组,指标按"销量/增长率"再分一层。对应到 API:两次header分别画分组行和列名行,Column::initial给固定宽度,Column::remainder吃掉剩余宽度。效果:
┌──────────┬──────────────┬────────────────┐ │ 产品线 │ 产品 │ 销量 │ ├──────────┼──────────────┼────────────────┤ │ 全部 │ 笔记本 │ 月销量 / 增长 │ ├──────────┼──────────────┼────────────────┤ │ 数码 │ ThinkPad X1 │ 1,200 / +12% │ │ 数码 │ 拯救者 7000 │ 800 / +8% │ └──────────┴──────────────┴────────────────┘滚动、条纹底纹、行点击选中都是现成开关,样式则改 egui 的主题视觉配置即可,不必为表格单写一套渲染代码。
⚠️ 常见坑与对策
- 以为要手动固定表头→ 表头本来就在滚动体上方;
min_scrolled_height/max_scroll_height只影响滚动区域高度。 - 表格下方挤不下内容→ 表格会吃满可用高度,用
StripBuilder给下方内容留条,或收紧max_scroll_height。 - 列宽不听话→
remainder会被多列均分,auto只按当前可见行计算;长文本列配合at_least、clip控制裁切。 - 几千行还逐行
row→ 改用TableBody::rows或heterogeneous_rows,按行高迭代器一次性声明,只有可见行真正绘制。 - 想要合并单元格→ 表格组件没有
col_span,跨列标题用两次header对齐列即可,真要合并需自行绘制。
继续深挖
- 表格组件源码 crates/egui_extras/src/table.rs:
TableBuilder、Column、TableBody的完整参数都在这里 - 官方表格 Demo crates/egui_demo_lib/src/demo/table_demo.rs:排序按钮、选中、滚动到指定行、十万行压力测试
- 主题与视觉定制 crates/egui/src/style.rs:条纹行、悬停、选中等颜色的落点
列宽分配算法和滚动区域的边界处理,是这份源码里最值得读的两个部分。
【免费下载链接】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),仅供参考