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?