I want to get an input from an entry on a button click and display that information when another button is clicked. This gives me an error because the closure takes ownership of my firstname
variable, in which I want to store the information.
How do I get the information out of the entry and reuse it?
// import gtk libs
extern crate gio;
extern crate gtk;
// declare use of gtk
use gtk::prelude::*;
fn main() {
let mut firstname = String::new();
if gtk::init().is_err() {
println!("Failed to initialize GTK.");
return;
}
let glade_src = include_str!("builder.glade");
let builder = gtk::Builder::new_from_string(glade_src);
let window: gtk::Window = builder.get_object("window1").unwrap();
let buttonSubmit: gtk::Button = builder.get_object("buttonSubmit").unwrap();
let buttonShow: gtk::Button = builder.get_object("buttonShow").unwrap();
let entryFirstname: gtk::Entry = builder.get_object("entryFirstname").unwrap();
// get information from entry
buttonSubmit.connect_clicked(move |_| {
firstname = entryFirstname.get_buffer().get_text();
});
// output information
let firstname_clone = firstname.clone();
buttonShow.connect_clicked(move |_| {
println!("Firstname: {}", firstname_clone);
});
window.show_all();
gtk::main();
}
Once your string has been moved inside the closures, the compiler can no longer check statically that your are not mixing read and write accesses to it. You need to use a RefCell
to enable runtime selection of read/write accesses, probably combined with Rc
for proper memory management:
let firstname = Rc::new(RefCell::new(String::new()));
let firstname_clone = firstname.clone();
// ...
buttonSubmit.connect_clicked(move |_| {
firstname.replace(entryFirstname.get_buffer().get_text());
});
// ...
buttonShow.connect_clicked(move |_| {
println!("Firstname: {}", firstname_clone.borrow());
});