The Rust GTK4 Book is great. Unfortuately though, if you are trying to get started with ListView, it cuts off right when things are starting to get interesting! Adding items to the ListView is cool, but in most cases we want to interact with them as well.
After some experimentation I found the following way of getting the currently selected ListView item. This assumes that you have followed along with the guide.
Firstly you need you to change the SelectionModel. The guide uses a NoSelection model:
// Wrap model with selection and pass it to the list view
let selection_model = NoSelection::new(Some(self.model()));
You’ll want to replace this with a SingleSelection
or MultiSelection
model as takes your fancy. Anything other than than the NoSelection
. I use jused a SingleSelection
since all I was worried about was one item being chosen.
let selection_model = SingleSelection::new(Some(self.model()));
Then you just need to bind to the selection_changed
signal. I did this in the setup_callbacks
method since it seemed the most appropriate place. I also tried doing this when originally creating the SingleSelection
model. Both worked. Keeping the callbacks together just seemed more maintainable. The ListStore
provides a convenient way to do this with the connect_selection_changed
method. This works quite well with the sample code provided in the book.
imp.list_view.model().unwrap().connect_selection_changed(|sel_model,position,items|{
println!("Selection changed");
let sel_idx = sel_model.selection_in_range(0,1).nth(0);
println!("{:?}",sel_idx);
let item = sel_model.item(sel_idx).unwrap().downcast::<SnippetObject>().expect("Nope");
println!("{:?}",item.property("path").unwrap());
println!("{:?}",item.property("title").unwrap());
});
You can also set this up using the connect_selected_item_notify
of the SingleSelection
model directly. If you are using the callback on the SingleSelection
model it doesn’t take the position and items parameters.