I am trying to change the string inside an egui label using a function. I made a reference to the content of the label and passed it along to the function but it doesn't change what is displayed in the application.
let mut label_text = "Change this".to_string();
egui::CentralPanel::default().show(ctx, |ui| {
ui.add(egui::Label::new(&label_text));
if ui.add(egui::Button::new("Press me")).clicked() {
do_stuff(&mut label_text, &ctx);
}
});
and the function do_stuff:
fn do_stuff(labeltext: &mut String, ctx: &egui::Context){
labeltext.clear();
labeltext.push_str("Changed");
ctx.request_repaint();
}
I am using the following dependencies in my toml:
eframe = "0.21.3"
egui = "0.21.0"
Also on the same topic how can I get a reference id for an egui widget so I can call that id from whatever function later on? From what I saw most widgets don't have an id or unique_id attribute anymore. Sorry if it's a noob question I am just starting out with Rust and Egui/Eframe, and it is all very confusing to me as in C++ every element of an UI would have an id which you could reference anywhere assign it to a handle and then change anything about that element.
Egui is an immediate-mode gui, which means that when you create a widget and call ui.add(widget)
, instead of that widget being added to some dom and then the whole scene being re-rendered, the rendering actually happens at that moment. This drawing code is then called again on each frame that needs to be rendered.
This means that your label_text
variable actually only existing during drawing, and any changes made to it will be lost once the drawing is finished. Then when drawing again, a new label_text
will be created.
In order to avoid this, you can add label_text
as a field of the struct you're implementing eframe::App
on. You can then refer to this variable within eframe::App::update
. This way it will live for as long as the app itself.
Here is a mcve with the changes:
struct MyApp {
label_text: String,
}
impl MyApp {
fn new() -> Self {
// Now you define `label_text` here
Self { label_text: "Change this".to_string() }
}
}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
// And you access it with `self.label_text` here
egui::CentralPanel::default().show(ctx, |ui| {
ui.add(egui::Label::new(&self.label_text));
if ui.add(egui::Button::new("Press me")).clicked() {
do_stuff(&mut self.label_text, &ctx);
}
});
}
}
fn do_stuff(label_text: &mut String, ctx: &egui::Context) {
label_text.clear();
label_text.push_str("Changed");
ctx.request_repaint();
}