如何在Egui中创建指定屏幕坐标范围的ScrollArea?
解决Egui中指定位置ScrollArea文本错位问题
我需要创建一个边界为指定屏幕坐标(x,y)至(z,w)的ScrollArea,类似HTML中固定宽高、可放置在屏幕任意位置的<div>。目前绘制的紫色容器边界范围正确,但ScrollArea内的文本却在容器外部;期望文本位于容器内,且能基于容器边界滚动。
当前代码片段:
let rect = Rect::from_min_max(pos2(80.0, 80.0), pos2(280.0, 280.0)); let frame = egui::Frame::none() .fill(Color32::from_rgb(232, 12, 232)) .paint(rect); ui.painter().add(frame); egui::ScrollArea::vertical() .max_height(280.0 - 80.0) .max_width(280.0 - 80.0) .show(ui, |ui| { ui.add(Label::new("long text".repeat(99))); });
完整代码:
use eframe::egui::{self, *}; fn main() { let native_options = eframe::NativeOptions::default(); eframe::run_native( "Arbitrary Scroll", native_options, Box::new(|_| Box::new(MyEguiApp)), ) .unwrap(); } struct MyEguiApp; impl eframe::App for MyEguiApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { let rect = Rect::from_min_max(pos2(80.0, 80.0), pos2(280.0, 280.0)); let frame = egui::Frame::none() .fill(Color32::from_rgb(232, 12, 232)) .paint(rect); ui.painter().add(frame); egui::ScrollArea::vertical() .max_height(280.0 - 80.0) .max_width(280.0 - 80.0) .show(ui, |ui| { ui.add(Label::new("long text".repeat(99))); }); }); } }
问题原因
你直接通过ui.painter()绘制的紫色容器是独立的图形操作,和ScrollArea的布局逻辑没有关联。ScrollArea默认遵循CentralPanel的布局流,从面板左上角开始渲染,因此和你手动绘制的紫色框位置错位。
两种可行解决方案
方案一:用ui.allocate_rect约束ScrollArea到指定区域
通过ui.allocate_rect在UI布局中预留指定的矩形空间,再让ScrollArea填充这个空间,确保文本和容器对齐:
impl eframe::App for MyEguiApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { let rect = Rect::from_min_max(pos2(80.0, 80.0), pos2(280.0, 280.0)); // 在UI布局中分配指定矩形区域 let response = ui.allocate_rect(rect, Sense::hover()); // 绘制紫色背景填充该区域 ui.painter().rect_filled(rect, 0.0, Color32::from_rgb(232, 12, 232)); // 在分配好的区域内创建ScrollArea egui::ScrollArea::vertical() .show_inside(ui, response.rect, |ui| { ui.add(Label::new("long text".repeat(99))); }); }); } }
方案二:用egui::Area创建固定位置容器(更贴近HTML固定div)
egui::Area专门用于创建可自由放置的UI容器,设置固定位置和尺寸后,内部的ScrollArea会自动约束在容器内:
impl eframe::App for MyEguiApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |_| { // 创建固定位置的Area容器 egui::Area::new("fixed_scroll_container") .fixed_pos(pos2(80.0, 80.0)) // 容器左上角坐标 .fixed_size(vec2(200.0, 200.0)) // 容器宽高(280-80) .show(ctx, |ui| { // 设置容器背景色为紫色 ui.style_mut().visuals.panel_fill = Color32::from_rgb(232, 12, 232); // 在容器内添加ScrollArea egui::ScrollArea::vertical() .show(ui, |ui| { ui.add(Label::new("long text".repeat(99))); }); }); }); } }
内容的提问来源于stack exchange,提问作者Coder100
相关产品推荐
相关产品推荐

