eframe中无法编辑egui::TextEdit::singleline()文本的问题求助
eframe/egui 单行文本框持久化编辑解决方案
问题根源
你在update里临时创建的"Add Folder".to_string()是每帧都会重新生成的临时变量,编辑后的值在下一帧就被新的初始化值覆盖了。而你尝试的两种方法都不符合Rust的内存安全规则:
- 返回
&'static mut String:函数内创建的字符串属于当前函数栈帧,函数执行完毕就会被释放,根本不能返回它的引用,所以触发E0515错误。 - 声明static可变字符串:static变量要求初始化值是编译期常量,但
String::from是运行时才会执行的方法,无法用于static初始化,所以报错。
正确实现:把字符串存在App结构体里
eframe的MyApp结构体就是用来保存应用状态的,把需要编辑的字符串作为结构体字段,就能让状态在帧之间持久保存。
修改后的完整代码:
use eframe::{App, egui, Frame, NativeOptions, run_native}; use eframe::egui::{CentralPanel, Color32, Context, SidePanel, Visuals}; use egui::RichText; #[derive(Default)] struct MyApp { add_folder_button_x: f32, add_folder_button_y: f32, folder_title: String, // 新增:保存文件夹标题的状态字段 } impl MyApp { fn new(cc: &eframe::CreationContext<'_>) -> Self { Self { add_folder_button_x: 100., add_folder_button_y: 50., folder_title: "Add Folder".to_string(), // 初始化默认值 } } } impl App for MyApp { fn update(&mut self, ctx: &Context, frame: &mut Frame) { SidePanel::left("LeftPanel").show(ctx, |ui| { ctx.set_visuals(Visuals { panel_fill: Color32::from_rgb(111, 255, 203), ..Visuals::default() }); // 直接引用结构体里的folder_title可变引用 let response = ui.add(egui::TextEdit::singleline(&mut self.folder_title)); if response.changed() { // 这里可以处理文本变化后的逻辑 println!("文件夹标题改为:{}", self.folder_title); } ui.put(egui::Rect::from_points(&[egui::Pos2::new(self.add_folder_button_x, self.add_folder_button_y)]), egui::Button::new("➕").fill(Color32::RED).wrap(false)); }); CentralPanel::default().show(ctx, |ui| { ctx.set_visuals(Visuals { panel_fill: Color32::from_rgb(111, 200, 203), ..Visuals::default() }); }); SidePanel::left("SecondLeft").show(ctx, |ui| { ctx.set_visuals(Visuals { panel_fill: Color32::from_rgb(100, 200, 180), ..Visuals::default() }); if ui.button("Clicker").clicked() {} if ui.add(egui::Button::new("➕").fill(Color32::RED)).clicked() {} if ui.button(RichText::new("delete").color(Color32::RED)).clicked() {} }); } } fn main() -> eframe::Result<()> { let native_options = NativeOptions::default(); run_native("TASK", native_options, Box::new(|cc| Box::new(MyApp::new(cc)))) }
关键修改点
- 结构体新增字段:给
MyApp添加folder_title: String,用来持久保存编辑的文本。 - 初始化默认值:在
new方法里把folder_title初始化为"Add Folder".to_string()。 - update里引用结构体字段:用
&mut self.folder_title作为TextEdit::singleline的参数,这样每帧都会使用同一个字符串实例,编辑内容会被保留。 - 移除不必要的unsafe:原代码里的
unsafe块是多余的,ctx.set_visuals不需要unsafe调用。
这样修改后,文本框的编辑内容就会在帧之间持久保存,不会再重置了。
内容的提问来源于stack exchange,提问作者Vecrix
相关产品推荐
相关产品推荐

