gtk3gladecustom-widgets

Exposing GTK3 custom widget properties in glade


I can add a custom widget to GTK, as shown here. Now I'd like to add properties to the custom widget and have them show up in glade. Is this possible?

I have added properties to the custom widget as shown here but the properties do not show up in glade.


Update

It appears that the glade catalogue supports a <parameter-spec> element that can be used to define properties to be exposed within glade as shown below.

<glade-widget-class title="Awesome TextView" name="AwesomeTextView" generic-name="awesome_text_view">
    <properties>
        <property id="num_fidgets" name="Number of fidgets" default="4" save="False" custom-layout="True">
        <parameter-spec>
            <type>GParamInt</type>
            <min>4</min>
        </parameter-spec>
        <tooltip>The number of fidgets</tooltip>
        </property>
    </properties>
</glade-widget-class>

I have defined one such property but it does not show in glade. Rather I get the error message:

GLib-GObject-CRITICAL **: 16:07:45.433: g_object_set_is_valid_property: object class 'AwesomeTextView' has no property named 'num-fidgets'

Where the custom widget AwesomeTextView is essentially defined as:

class AwesomeTextView (Gtk.TextView):
    __gtype_name__ = 'AwesomeTextView'
    
    num_fidgets = GObject.Property(type=int, default='4', nick='num_Fidgets')

The <parameter-spec>s appear to be undocumented. Thankfully though there are examples of the the supported <type>s in the glade repo.

Correction: <parameter-spec>s are documented. This documentation can be supplemented with examples of the supported <type>s in the glade repo.


Update2

Found the cause of the error. The default argument has the wrong type -- str instead of int. The property should be:

num_fidgets = GObject.Property(type=int, default=4, nick='num_Fidgets')

Glade no longer emits an error. But the property does not show up in the UI.


Solution

  • Overly complicated solution (See update for simpler solution)

    Found the final piece. Do not set the <property> attribute custom-layout to "True" -- unless you know what are doing i.e. you know how to layout the property, properly (I don't, at least not yet). My advise, set custom-layout="False" in the updated catalogue shown below:

    <glade-catalog name="awesome_text_view" library="gladepython" domain="glade-3" depends="gtk+">
        <init-function>glade_python_init</init-function>
    
        <glade-widget-classes>
            <glade-widget-class title="Awesome TextView" name="AwesomeTextView" generic-name="awesome_text_view">
                <properties>
                    <property id="num_fidgets" name="Number of fidgets" default="4" save="True" custom-layout="False">
                        <parameter-spec>
                            <type>GParamInt</type>
                            <min>4</min>
                        </parameter-spec>
                        <tooltip>The number of fidgets</tooltip>
                    </property>
                </properties>
            </glade-widget-class>
        </glade-widget-classes>
    
        <glade-widget-group name="Python" title="Python">
            <glade-widget-class-ref name="AwesomeTextView"/>
        </glade-widget-group>
    </glade-catalog>
    

    Result:

    custom widget property in glage

    For completeness here is the sample custom widget class

    import gi
    gi.require_version("Gtk", "3.0")
    from gi.repository import GObject
    from gi.repository import Gtk
    
    class AwesomeTextView(Gtk.TextView):
        __gtype_name__ = 'AwesomeTextView'
        num_fidgets = GObject.Property(type=int, default=4, nick='num_fidgets')
    
        def __init__(self):
            Gtk.TextView.__init__(self)
    

    Update

    Turns out the nick argument in the property declaration

    num_fidgets = GObject.Property(type=int, default=4, nick='num_fidgets')
    

    is all that's required to for the property to show up in the glade UI. The element <properties> would be more appropriate for more complicated values e.g. enums. I'm leaving the more complicated answer in place in the event that its of use to anyone.