How to use replacements for Gtk.TreeView (Gtk.ColumnView/Gtk.TreeListMode/Gtk.TreeExpander)

Hello everyone!!

I wanted to build a tree in Gtk, but when I read about Gtk.TreeVIew, I saw that it was deprecated, and that as such I should use Gtk.ColumnView.

This did not sound too bad since Gtk.ColumnView seems to use Gio.ListModel structures and I thought it wouldn’t bee hard since I’ve worked with ListModels before…

However, it was not!

Currently, I’m wondering how to do anything at all with the Gtk.ColumnView and all the widgets I think I need to use it with: Gtk.TreeListMode/Gtk.TreeExpander

I’ve scoured the internet for a few minutes but I couldn’t find a guide that explains or atleast hints on how to use it. I expected it to be easy because it was super simple to use Gtk.ListView, but for Gtk.ColumnView I don’t have any hint.

could be nice if someone could maybe show me the general idea on how to use it as is done here for Gtk.ListView:

static void
setup_listitem_cb (GtkListItemFactory *factory,
                  GtkListItem        *list_item)
 GtkWidget *image;

 image = gtk_image_new ();
 gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
 gtk_list_item_set_child (list_item, image);

static void
bind_listitem_cb (GtkListItemFactory *factory,
                 GtkListItem        *list_item)
 GtkWidget *image;
 GAppInfo *app_info;

 image = gtk_list_item_get_child (list_item);
 app_info = gtk_list_item_get_item (list_item);
 gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (app_info));

static void
activate_cb (GtkListView  *list,
            guint         position,
            gpointer      unused)
 GAppInfo *app_info;

 app_info = g_list_model_get_item (G_LIST_MODEL (gtk_list_view_get_model (list)), position);
 g_app_info_launch (app_info, NULL, NULL, NULL);
 g_object_unref (app_info);


 model = create_application_list ();

 factory = gtk_signal_list_item_factory_new ();
 g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL);
 g_signal_connect (factory, "bind", G_CALLBACK (bind_listitem_cb), NULL);

 list = gtk_list_view_new (GTK_SELECTION_MODEL (gtk_single_selection_new (model)), factory);

 g_signal_connect (list, "activate", G_CALLBACK (activate_cb), NULL);

 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), list);

thank you

GTK 4 has a gtk4-demo application with various examples, including a GtkTreeListModel demo that you can look for inspiration:

It shows how to use:

  • GtkTreeListModel
  • GtkTreeExpander
  • GtkColumnView

The UI is built using GtkBuilderListItemFactory but it can be easily moved to a GtkSignalListItemFactory and writing the row item widgets in code as opposed to UI definition files.

Having a tutorial for the GNOME developer documentation website would be great, if you want to contribute one.

thanks. my hero!!

I’m not very familiar with C, so I’ll first have to convert the code to a language I understand. thanks though!!

spoke too soon! the code is way too complex for me :frowning:

also is it even possible to have a tree view (tree view replacement) with expandable rows?? the demo has expandable rows and a table but they are not combined to make a tree view.

I’m porting Python GTK demos to GTK4 here and the main window for it is complete. It uses Gtk.ListView, Gtk.TreeListModel and Gtk.TreeExpander in order to create a sidebar with expandable sections.

Class InfoTreeListBuilder and method DemoAppWindow.build_sidebar() show how to use them in Python (which may be easier to understand than C).

I’m not sure what you mean by that. But if you are asking about indefinite nesting of rows then yes. You can nest as much as you want.

thanks I’ll take a look. I meant, in the gtk demo app, there is an expandable view and a table view, but not both

is it even possible to have a table whose rows can also expand (a tree view)

Since I didn’t need to (yet), I didn’t look into Gtk.ColumnView. So, I’m not sure. But probably yes.

I now believe it’s possible, because nautilus can do it.

the remaining task is to know how they do it