I have a two widgets in a simple GTK app:
extern crate gdk;
extern crate gtk;
use super::desktop_entry::DesktopEntry;
use gdk::enums::key;
use gtk::prelude::*;
pub fn launch_ui(_desktop_entries: Vec<DesktopEntry>) {
gtk::init().unwrap();
let builder = gtk::Builder::new_from_string(include_str!("interface.glade"));
let window: gtk::Window = builder.get_object("main_window").unwrap();
let search_entry: gtk::SearchEntry = builder.get_object("search_entry").unwrap();
let list_box: gtk::ListBox = builder.get_object("list_box").unwrap();
window.show_all();
search_entry.connect_search_changed(move |_se| {
let _a = list_box.get_selected_rows();
});
window.connect_key_press_event(move |_, key| {
match key.get_keyval() {
key::Down => {
list_box.unselect_all();
}
_ => {}
}
gtk::Inhibit(false)
});
gtk::main();
}
I need to change list_box from both events. I have two closures that move, but it is not possible to move list_box to both closures simultaneously as I get the error:
error[E0382]: capture of moved value: `list_box`
What can I do?
You literally cannot do this. I encourage you to go back and re-read The Rust Programming Language to refresh yourself on ownership. When a non-
Copytype is moved, it's gone — this is a giant reason that Rust even exists: to track this so the programmer doesn't have to.If a type is
Copy, the compiler will automatically make the copy for you. If a type isClone, then you must invoke the clone explicitly.You will need to change to shared ownership and most likely interior mutability.
Shared ownership allows a single piece of data to be jointly owned by multiple values, creating additional owners via cloning.
Interior mutability is needed because Rust disallows multiple mutable references to one item at the same time.
Wrap your
list_boxin aMutexand then anArc(Arc<Mutex<T>>). Clone theArcfor each handler and move that clone into the handler. You can then lock thelist_boxand make whatever changes you need.See also: