Handle Signals of Child Widgets in a GridView

I am struggling with understanding the GridView, ListModel, and ListItem.

I have created a template .ui file for my ListItem which is a composite of widget. For example, the widget may show an album cover, and have an overlay for favoriting it, plus a button to bring up a box to write a comment.

My .ui file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <template class="GtkListItem">
    <property name="child">
      
      <object class="GtkBox" id="album">
        <property name="name">album</property>
        <property name="orientation">1</property>
        <property name="halign">3</property>

        <child>
          <object class="GtkOverlay" id="overlay1">
            <property name="visible">True</property>

            <child>
              <object class="GtkImage">
                <property name="name">cover</property>
                <property name="icon-name">media-tape-symbolic</property>
                <property name="pixel-size">96</property>
                <style>
                  <class name="icon-dropshadow"/>
                </style>
              </object>
            </child>

            <child type="overlay">
              <object class="GtkButton" id="edit-comment">
                <property name="css-classes">comment-overlay</property>
                <property name="visible">True</property>
                <property name="label">Edit Comment</property>
                <property name="halign">fill</property>
                <property name="valign">end</property>
              </object>
            </child>
            
          </object>
        </child>
        <child>
          <object class="GtkLabel" id="album-band">
            <property name="label"></property>
            <property name="ellipsize">3</property>
            <property name="lines">1</property>
            <property name="max-width-chars">1</property>
            <property name="single-line-mode">true</property>
            <property name="wrap">false</property>
            <property name="width-chars">1</property>
            <binding name="label">
              <lookup name="artist" type="CampCounselorAlbum">
                <lookup name="item">GtkListItem</lookup>
              </lookup>
            </binding>
          </object>
        </child>
        <child>
          <object class="GtkLabel" id="album-title">
            <property name="label"></property>
            <property name="ellipsize">3</property>
            <property name="lines">1</property>
            <property name="max-width-chars">1</property>
            <property name="single-line-mode">true</property>
            <property name="wrap">false</property>
            <property name="width-chars">1</property>
            <binding name="label">
              <lookup name="album" type="CampCounselorAlbum">
                <lookup name="item">GtkListItem</lookup>
              </lookup>
            </binding>
          </object>
        </child>
        <child>
          <object class="GtkLinkButton">
            <property name="label">View on Site</property>
            <property name="uri"></property>
            <binding name="uri">
              <lookup name="url" type="CampCounselorAlbum">
                <lookup name="item">GtkListItem</lookup>
              </lookup>
            </binding>
          </object>
        </child>
      </object>
    </property>
  </template>
</interface>

So far, everything is good. My items are drawing as expected and labels are pulling relevant data from the model by binding and using lookups.

I am instantiating this using the BuilderListItemFactory, like:

var albums_list_model = new AlbumListModel();
		
var scrolled_window = new Gtk.ScrolledWindow();
set_child(scrolled_window);

try {
	var factory = new Gtk.BuilderListItemFactory.from_resource(null, "/net/line72/campcounselor/ui/album.ui");

	var selection = new Gtk.NoSelection(albums_list_model);
	var grid_view = new Gtk.GridView(selection, factory);
	grid_view.set_hscroll_policy(Gtk.ScrollablePolicy.NATURAL);
	grid_view.set_vscroll_policy(Gtk.ScrollablePolicy.NATURAL);
			
	scrolled_window.set_child(grid_view);
} catch (GLib.Error e) {
	stdout.printf("!!ERROR: %s\n", e.message);
}

My question is, in my .ui file, I have a GtkButton with id edit-comment. How do I bind a clicked signal to that?

It seems I could switch over to a SignalListItemFactory and manually connect/disconnect a signal in the bind/unbind, but then I don’t think I’d be able to use my .ui file.

What options do I have?

TIA.

Shouldn’t this work? Just connect the signal via standard GtkBuilder <signal> syntax, then in your handler, you’ll get the pointer to the Button, from which you should be able to ‘walk’ back up to the ListItem via get_parent(), then from that ListItem you can use its :item property to get the model item and update it as per the edited coment, etc.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.