GtkBuilderListItemFactory: property 'scope' for type 'GtkBuilderListItemFactory' cannot be set twice

I’m trying to use the example to handle a signal in GtkBuilderListItemFactory from here and I’m getting an warning Warning: g_object_new_is_valid_property: property 'scope' for type 'GtkBuilderListItemFactory' cannot be set twice . How to fix this warning ? Maybe in pygobject Builder need check if scope exist before self.set_scope(Builder.BuilderScope(scope_object_or_map))

Minimal example

import gi
gi.require_version('Gtk', '4.0')

from gi.repository import Gtk, GLib, Gio
from gi.repository import GObject

UI_XML = """<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <object class="GtkWindow">
    <property name="title">Test window</property>
    <property name="visible">true</property>
    <child>
      <object class="GtkBox">
        <property name="orientation">1</property>
        <child>
          <object class="GtkListView">
            <property name="factory">
              <object class="GtkBuilderListItemFactory">
                <property name="scope">
                  <object class="ListItemBuilderScope"></object>
                </property>
                <property name="bytes"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <template class="GtkListItem">
    <property name="child">
      <object class="GtkButton">
        <binding name="label">
          <lookup name="objName" type="MyObject">
            <lookup name="item" type="GtkListItem">
              <constant>GtkListItem</constant>
            </lookup>
          </lookup>
        </binding>
        <signal name="clicked" handler="test"/>
      </object>
    </property>
  </template>
</interface>]]></property>
              </object>
            </property>
            <property name="model">
              <object class="GtkNoSelection">
                <property name="model">
                  <object class="MyList">
                    <child>
                      <object class="MyObject">
                        <property name="objName">first</property>
                      </object>
                    </child>
                    <child>
                      <object class="MyObject">
                        <property name="objName">second</property>
                      </object>
                    </child>
                  </object>
                </property>
              </object>
            </property>
          </object>
        </child>
      </object>
    </child>
  </object>
</interface>"""

class MyObject(GObject.GObject):
    __gtype_name__ = "MyObject"

    def __init__(self):
        GObject.GObject.__init__(self)
        self.value = ""

    @GObject.Signal
    def test(self, *args):
        print("Handler ", self.value, " ", args)

    @GObject.Property(type=str)
    def objName(self):
        return self.value

    @objName.setter
    def objName(self, value):
        self.value = value

class MyList(GObject.GObject, Gio.ListModel, Gtk.Buildable):
    __gtype_name__ = "MyList"
    def __init__(self) -> None:
        GObject.GObject.__init__(self)
        self._list = []

    def do_add_child(self, builder, child, type):
        self._list.append(child)

    def do_get_item(self, index):
        return self._list[index]
    
    def do_get_item_type(self):
        return GObject.TYPE_OBJECT

    def do_get_n_items(self):
        return len(self._list)


class ListItemBuilderScope(GObject.GObject, Gtk.BuilderScope):
    __gtype_name__ = "ListItemBuilderScope"
    def __init__(self, scope_object=None):
            super().__init__()
            self._scope_object = scope_object

    def do_create_closure(self, builder, func_name, flags, obj):
        current_object = builder.get_current_object() or self._scope_object
        item = current_object.get_item()
        def call_signal(source):
            item.emit(func_name)
        return call_signal

class App(Gtk.Application):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.builder = None

    def do_activate(self):
        self.builder = Gtk.Builder()
        self.builder.add_from_string(UI_XML)

if __name__ == "__main__":
    app = App()
    app.hold()
    app.run()

And maybe there are plans to add a call signal from builder to custom object in future?

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