Rust List View: Get Your Selection

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.