Search code examples
rustgtk-rs

How do I get information from an entry on button click?


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();
}

Solution

  • 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());
    });