Search code examples
rustgtkgtk-rs

Seemingly nothing happens when attempting to add to a `gtk::ListBox` from within an event handler in GTK-RS application


I'm attempting to to add to a gtk::ListBox container from within the event handling closure of an unrelated widget. The list box in question is fetched via a gtk::Builder like so:

let notes_list: gtk::ListBox = builder.get_object(NOTES_LIST_BOX_ID).unwrap();

And the event handler where I can't seem to add to notes_list (note that I've tried without the clone! macro, with strong and weak references, wrapping in Rc pointer, etc. but nothing seems to change):

open_menu_item.connect_activate(clone!(@strong state, @strong notes_list => move |_| {
    println!("Open database menu item activated");

    // Seemingly can't add to notes_list from within this closure???
    notes_list.add(&gtk::Label::new(Some("TEST"))); // Doesn't work???

    let dialog = gtk::FileChooserDialog::with_buttons::<gtk::Window>(
        Some("Open database file"),
        None,
        gtk::FileChooserAction::Open,
        &[("_Cancel", gtk::ResponseType::Cancel),
          ("_Open", gtk::ResponseType::Accept)]
    );

    dialog.connect_response(clone!(@weak state, @weak notes_list => move |this, res| {
        if res == gtk::ResponseType::Accept {
            let file = this.get_file().unwrap();
            let path_buf = file.get_path().unwrap();

            println!("Opening database file: {}", path_buf.as_path().display());

            let mut state = state.borrow_mut();

            state.db = database::database_in_file(path_buf.as_path()).ok();
            state.update_notes_list(&notes_list);
        }

        this.close();
    }));

    dialog.show_all();
}));

No error message is presented - the expected behaviour (i.e. the addition of a gtk::Label to the list box) does not occur.

The full code of this module (and the rest of my messy code base): https://github.com/WiredSound/nos/blob/master/src/gui.rs

If anyone could help me figure this out then I'd really appreciate it, thanks.


Solution

  • Widgets, in GTK3, are hidden by default. This means that calling show_all() on a container will show all its current children. If you add a new child, you're responsible for calling show() on it in order to make it visible.

    In your signal handler, you're adding a gtk::Label to the list box, but you need to make it visible as well.