rustgtk4gtk-rs

How do you limit the number of GtkColumnView rows


I'm trying to reduce the load time of a ColumnView widget with lots of rows. quoting from gtk list widget documentation:

While it is not a problem for short lists to instantiate widgets for every item in the model, once lists grow to thousands or millions of elements, this gets less feasible. Because of this, the views only create a limited amount of listitems and recycle them by binding them to new items. In general, views try to keep listitems available only for the items that can actually be seen on screen.

However in my code example although the recycling(bind, unbind) works; 205 items are setup; whereas only a few items are visible:

use gtk::*;
use gtk::prelude::*;
use gtk::gio::ListStore;
use gtk::glib::BoxedAnyObject;

fn main() {
    let application = Application::builder().application_id("column.view.test").build();
    application.connect_activate(|application| {
        let list_store = ListStore::new(BoxedAnyObject::static_type());
        for i in 0..10000 {
            list_store.append(&BoxedAnyObject::new(i));
        }
        let column_view = ColumnView::builder().model(&NoSelection::new(Some(list_store))).build();
        let scrolled_window = ScrolledWindow::builder().child(&column_view).build();
        let item_factory = SignalListItemFactory::new();
        item_factory.connect_setup(|_, item| {
            let list_item = item.downcast_ref::<ListItem>().unwrap();
            list_item.set_child(Some(&Label::new(None)));
            println!("setup");
        });
        item_factory.connect_bind(|_, item| {
            let list_item = item.downcast_ref::<ListItem>().unwrap();
            list_item.child().and_downcast::<Label>().unwrap().set_label("a");
            println!("bind");
        });
        item_factory.connect_unbind(|_, _| { println!("unbind"); });
        item_factory.connect_teardown(|_, _| { println!("teardown"); });
        column_view.append_column(&ColumnViewColumn::builder().factory(&item_factory).build());
        ApplicationWindow::builder().application(application).child(&scrolled_window).build().present();
    });
    application.run();
}

How can I setup only items that are visible(or a bit more) or a hard coded amount of items to reduce the load time of my widget?


Solution

  • The very short answer is : you can’t. I had the same problem trying to use a few heavy weight large items (Texteditor, WEbKit View). The widget is work in progress and you might need to create your own widget if you really think you need to. At least that is what I do.