Builder derived widgets with properties -- error validate_and_install_class_property: assertion 'class->set_property != NULL' failed

Dan Lo Forte <[email protected]> Mon, 29 Aug 2022 17:37:36 -0400
Newsgroups gmane.comp.gnome.gtkmm
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--===============2136688453207995703==
Content-Type: multipart/alternative;
 boundary="------------RiTsGHXGDD0CK87EVLXWRgJ8"
Content-Language: en-US

This is a multi-part message in MIME format.
--------------RiTsGHXGDD0CK87EVLXWRgJ8
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit

I have a glade file from which I load a derived widget that has a 
Glib::Property.  When I load the main window, I get the following error:

```

GLib-GObject-CRITICAL **: validate_and_install_class_property: assertion 
'class->set_property != NULL' failed

```

I have created a simplified example, as per this page: 
https://developer-old.gnome.org/gtkmm-tutorial/stable/sec-builder-using-derived-widgets.html.en, 
using a derived Gtk::Button and still see the error.

I have included Glib::ObjectBase() in the initializer list of the 
derived widget and called the default constructor which also has a the 
Glib::ObjectBase() to initialize the Gtype (), but I still see the error.


Additionally, the property appears to work, in that I can connect to the 
signal_changed and set/get the property value as expected, but still 
receive the error at runtime.


Simplified example:

```

#include <iostream> #include <gtkmm.h> Glib::ustring glade_str =
"<?xml version=\"1.0\"encoding=\"UTF-8\"?>\n" "<!-- Generated with glade 
3.38.2 -->\n" "<interface>\n" " <requires 
lib=\"gtk+\"version=\"3.24\"/>\n" " <object 
class=\"GtkWindow\"id=\"mainwindow\">\n" " <property 
name=\"can-focus\">False</property>\n" " <child>\n" " <object 
class=\"GtkButton\"id=\"btn\">\n" " <property 
name=\"label\"translatable=\"yes\">button</property>\n" " <property 
name=\"visible\">True</property>\n" " <property 
name=\"can-focus\">True</property>\n" " <property 
name=\"receives-default\">True</property>\n" " </object>\n" " 
</child>\n" " </object>\n" "</interface>"; class DerivedButtonProp :public Gtk::Button {
public:
     static void ensure_type()
     {
         std::cout<< __PRETTY_FUNCTION__ << std::endl; static_cast<void>(DerivedButtonProp()); }

     DerivedButtonProp(BaseObjectType *obj, Glib::RefPtr<Gtk::Builder> const &builder)
             :Glib::ObjectBase(s_type_name), Gtk::Button(obj), prop_mynum(*this, "mynumprop")
     {
         std::cout<< __PRETTY_FUNCTION__ << std::endl; }

     virtual ~DerivedButtonProp() =default; Glib::PropertyProxy<int> mynum() {return prop_mynum.get_proxy(); }; private:
     DerivedButtonProp()
             :Glib::ObjectBase(s_type_name), prop_mynum(*this, "mynumprop")
     {
         std::cout<< __PRETTY_FUNCTION__ << std::endl; }; static constexpr auto s_type_name ="DerivedButtonProp"; Glib::Property<int> prop_mynum; }; class App :public Gtk::Window {
public:
     App()
     {

     }

     App(BaseObjectType *obj, Glib::RefPtr<Gtk::Builder> const & builder)
             :Gtk::Window(obj)
     {
         builder->get_widget_derived("btn", btn_derprop); }

     virtual ~App() =default; protected:
     DerivedButtonProp *btn_derprop =nullptr; }; App* pWindow =nullptr; Glib::RefPtr<Gtk::Application> app; int main(int argc, char *argv[])
{
Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(); DerivedButtonProp::ensure_type(); Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_string(glade_str); App *pWindow =nullptr; builder->get_widget_derived("mainwindow", pWindow); app->run(*pWindow); }

```

--------------RiTsGHXGDD0CK87EVLXWRgJ8
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit

<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>I have a glade file from which I load a derived widget that has a
      Glib::Property.  When I load the main window, I get the following
      error:</p>
    <p>```</p>
    <p>GLib-GObject-CRITICAL **: validate_and_install_class_property:
      assertion 'class-&gt;set_property != NULL' failed</p>
    <p>```</p>
    <p>I have created a simplified example, as per this page:
<a class="moz-txt-link-freetext" href="https://developer-old.gnome.org/gtkmm-tutorial/stable/sec-builder-using-derived-widgets.html.en">https://developer-old.gnome.org/gtkmm-tutorial/stable/sec-builder-using-derived-widgets.html.en</a>,
      using a derived Gtk::Button and still see the error.<br>
    </p>
    <p>I have included Glib::ObjectBase() in the initializer list of the
      derived widget and called the default constructor which also has a
      the Glib::ObjectBase() to initialize the Gtype (), but I still see
      the error.</p>
    <p><br>
    </p>
    <p>Additionally, the property appears to work, in that I can connect
      to the signal_changed and set/get the property value as expected,
      but still receive the error at runtime.</p>
    <p><br>
    </p>
    <p>Simplified example:</p>
    <p>```</p>
    <pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono',monospace;font-size:9.8pt;"><span style="color:#bbb529;">#include </span><span style="color:#6a8759;">&lt;iostream&gt;
</span><span style="color:#bbb529;">#include </span><span style="color:#6a8759;">&lt;gtkmm.h&gt;
</span><span style="color:#6a8759;">
</span><span style="color:#b5b6e3;">Glib</span>::<span style="color:#b5b6e3;">ustring </span>glade_str =
<span style="color:#6a8759;">"&lt;?xml version=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">1.0</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;"> encoding=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">UTF-8</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">?&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"&lt;!-- Generated with glade 3.38.2 --&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"&lt;interface&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"  &lt;requires lib=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">gtk+</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;"> version=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">3.24</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">/&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"  &lt;object class=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">GtkWindow</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;"> id=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">mainwindow</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"    &lt;property name=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">can-focus</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">&gt;False&lt;/property&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"    &lt;child&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"      &lt;object class=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">GtkButton</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;"> id=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">btn</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"        &lt;property name=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">label</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;"> translatable=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">yes</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">&gt;button&lt;/property&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"        &lt;property name=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">visible</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">&gt;True&lt;/property&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"        &lt;property name=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">can-focus</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">&gt;True&lt;/property&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"        &lt;property name=</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">receives-default</span><span style="color:#cc7832;">\"</span><span style="color:#6a8759;">&gt;True&lt;/property&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"      &lt;/object&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"    &lt;/child&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"  &lt;/object&gt;</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">"
</span><span style="color:#6a8759;">"&lt;/interface&gt;"</span><span style="color:#cc7832;">;
</span><span style="color:#cc7832;">
</span><span style="color:#cc7832;">class </span><span style="color:#b5b6e3;">DerivedButtonProp </span>: <span style="color:#cc7832;">public </span><span style="color:#b5b6e3;">Gtk</span>::<span style="color:#b5b6e3;">Button </span>{
<span style="color:#cc7832;">public</span>:
    <span style="color:#cc7832;">static void </span><span style="color:#ffc66d;">ensure_type</span>()
    {
        <span style="color:#b5b6e3;">std</span>::cout <span style="color:#5f8c8a;">&lt;&lt; </span><span style="color:#908b25;">__PRETTY_FUNCTION__ </span><span style="color:#5f8c8a;">&lt;&lt; </span><span style="color:#b5b6e3;">std</span>::endl<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">        static_cast</span>&lt;<span style="color:#cc7832;">void</span>&gt;(DerivedButtonProp())<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">    </span>}

    <span style="color:#ffc66d;">DerivedButtonProp</span>(<span style="color:#b9bcd1;">BaseObjectType </span>*obj<span style="color:#cc7832;">, </span><span style="color:#b5b6e3;">Glib</span>::<span style="color:#b5b6e3;">RefPtr</span>&lt;<span style="color:#b5b6e3;">Gtk</span>::<span style="color:#b5b6e3;">Builder</span>&gt; <span style="color:#cc7832;">const </span>&amp;builder)
            : <span style="color:#b5b6e3;">Glib</span>::ObjectBase(<span style="color:#9373a5;">s_type_name</span>)<span style="color:#cc7832;">,
</span><span style="color:#cc7832;">              </span><span style="color:#b5b6e3;">Gtk</span>::Button(obj)<span style="color:#cc7832;">,
</span><span style="color:#cc7832;">              </span><span style="color:#9373a5;">prop_mynum</span>(*<span style="color:#cc7832;">this, </span><span style="color:#6a8759;">"mynumprop"</span>)
    {
        <span style="color:#b5b6e3;">std</span>::cout <span style="color:#5f8c8a;">&lt;&lt; </span><span style="color:#908b25;">__PRETTY_FUNCTION__  </span><span style="color:#5f8c8a;">&lt;&lt; </span><span style="color:#b5b6e3;">std</span>::endl<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">    </span>}

    <span style="color:#cc7832;">virtual </span><span style="color:#ffc66d;">~DerivedButtonProp</span>() = <span style="color:#cc7832;">default;
</span><span style="color:#cc7832;">
</span><span style="color:#cc7832;">    </span><span style="color:#b5b6e3;">Glib</span>::<span style="color:#b5b6e3;">PropertyProxy</span>&lt;<span style="color:#cc7832;">int</span>&gt; <span style="color:#ffc66d;">mynum</span>() { <span style="color:#cc7832;">return </span><span style="color:#9373a5;">prop_mynum</span>.get_proxy()<span style="color:#cc7832;">; </span>}<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">
</span><span style="color:#cc7832;">private</span>:
    <span style="color:#ffc66d;">DerivedButtonProp</span>()
            : <span style="color:#b5b6e3;">Glib</span>::ObjectBase(<span style="color:#9373a5;">s_type_name</span>)<span style="color:#cc7832;">,
</span><span style="color:#cc7832;">              </span><span style="color:#9373a5;">prop_mynum</span>(*<span style="color:#cc7832;">this, </span><span style="color:#6a8759;">"mynumprop"</span>)
    {
        <span style="color:#b5b6e3;">std</span>::cout <span style="color:#5f8c8a;">&lt;&lt; </span><span style="color:#908b25;">__PRETTY_FUNCTION__  </span><span style="color:#5f8c8a;">&lt;&lt; </span><span style="color:#b5b6e3;">std</span>::endl<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">    </span>}<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">
</span><span style="color:#cc7832;">    static constexpr auto </span><span style="color:#9373a5;">s_type_name </span>= <span style="color:#6a8759;">"DerivedButtonProp"</span><span style="color:#cc7832;">;
</span><span style="color:#cc7832;">    </span><span style="color:#b5b6e3;">Glib</span>::<span style="color:#b5b6e3;">Property</span>&lt;<span style="color:#cc7832;">int</span>&gt; <span style="color:#9373a5;">prop_mynum</span><span style="color:#cc7832;">;
</span>}<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">
</span><span style="color:#cc7832;">class </span><span style="color:#b5b6e3;">App </span>: <span style="color:#cc7832;">public </span><span style="color:#b5b6e3;">Gtk</span>::<span style="color:#b5b6e3;">Window </span>{
<span style="color:#cc7832;">public</span>:
    <span style="color:#ffc66d;">App</span>()
    {

    }

    <span style="color:#ffc66d;">App</span>(<span style="color:#b9bcd1;">BaseObjectType </span>*obj<span style="color:#cc7832;">, </span><span style="color:#b5b6e3;">Glib</span>::<span style="color:#b5b6e3;">RefPtr</span>&lt;<span style="color:#b5b6e3;">Gtk</span>::<span style="color:#b5b6e3;">Builder</span>&gt; <span style="color:#cc7832;">const </span>&amp; builder)
            : <span style="color:#b5b6e3;">Gtk</span>::Window(obj)
    {
        builder<span style="color:#5f8c8a;">-&gt;</span>get_widget_derived(<span style="color:#6a8759;">"btn"</span><span style="color:#cc7832;">, </span><span style="color:#9373a5;">btn_derprop</span>)<span style="color:#cc7832;">;
</span><span style="color:#808080;">    </span>}

    <span style="color:#cc7832;">virtual </span><span style="color:#ffc66d;">~App</span>() = <span style="color:#cc7832;">default;
</span><span style="color:#cc7832;">
</span><span style="color:#cc7832;">protected</span>:
    <span style="color:#b5b6e3;">DerivedButtonProp </span>*<span style="color:#9373a5;">btn_derprop </span>= <span style="color:#cc7832;">nullptr;
</span><span style="color:#808080;">
</span>}<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">
</span><span style="color:#cc7832;">
</span><span style="color:#b5b6e3;">App</span>* pWindow = <span style="color:#cc7832;">nullptr;
</span><span style="color:#b5b6e3;">Glib</span>::<span style="color:#b5b6e3;">RefPtr</span>&lt;<span style="color:#b5b6e3;">Gtk</span>::<span style="color:#b5b6e3;">Application</span>&gt; app<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">
</span><span style="color:#808080;"></span><span style="color:#cc7832;">int </span><span style="color:#ffc66d;">main</span>(<span style="color:#cc7832;">int </span>argc<span style="color:#cc7832;">, char </span>*argv[])
{
<span style="color:#808080;">    </span><span style="color:#b5b6e3;">Glib</span>::<span style="color:#b5b6e3;">RefPtr</span>&lt;<span style="color:#b5b6e3;">Gtk</span>::<span style="color:#b5b6e3;">Application</span>&gt; app = <span style="color:#b5b6e3;">Gtk</span>::<span style="color:#b5b6e3;">Application</span>::create()<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">    </span><span style="color:#b5b6e3;">DerivedButtonProp</span>::ensure_type()<span style="color:#cc7832;">;
</span><span style="color:#808080;">    </span><span style="color:#b5b6e3;">Glib</span>::<span style="color:#b5b6e3;">RefPtr</span>&lt;<span style="color:#b5b6e3;">Gtk</span>::<span style="color:#b5b6e3;">Builder</span>&gt; builder = <span style="color:#b5b6e3;">Gtk</span>::<span style="color:#b5b6e3;">Builder</span>::create_from_string(glade_str)<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">
</span><span style="color:#cc7832;">    </span><span style="color:#b5b6e3;">App </span>*pWindow = <span style="color:#cc7832;">nullptr;
</span><span style="color:#cc7832;">    </span>builder<span style="color:#5f8c8a;">-&gt;</span>get_widget_derived(<span style="color:#6a8759;">"mainwindow"</span><span style="color:#cc7832;">, </span>pWindow)<span style="color:#cc7832;">;
</span><span style="color:#cc7832;">    </span>app<span style="color:#5f8c8a;">-&gt;</span>run(*pWindow)<span style="color:#cc7832;">;
</span>}</pre>
    <p>```<br>
    </p>
  </body>
</html>

--------------RiTsGHXGDD0CK87EVLXWRgJ8--

--===============2136688453207995703==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
gtkmm-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/gtkmm-list

--===============2136688453207995703==--