I've created a custom Gtk Widget with a template, and I want to use it on other Gtk Builder file.
What I've done:
<template class="G3JAMinScenes" parent="GtkBox">
when I create it with g3jamin_scenes_new
the widget works as expected, the problem is that I want to add it as child of a window using Gtk Builder, so I wrote:
...
<child>
<object class="G3JAMinScenes" parent="GtkBox" id="scnes">
</object>
</child>
...
but it throws an error when I try to run:
Gtk-CRITICAL **: Error building template class 'G3JAMinAppWindow' for an instance of type 'G3JAMinAppWindow': Invalid object type `G3JAMinScenes'
I haven't been able to find any official answer to this in any documentation. I went digging through the GTK+ source and found a few things though.
When GtkBuilder
sees a type it doesn't know about yet, it tries to obtain a function that returns the relevantGType
. It will try a couple of heuristics to determine what function to call. If you are using one of the G_DEFINE_TYPE
family of macros, it will generate the necessary mywidget_get_type
style function that is needed. If you are doing something weird, you can also specify the function in the type-func
attribute for the object in your ui file.
But, for simple programs that probably isn't going to work (at least on Linux) because the compiler probably isn't going to export the function in the dynamic symbol table, and so GtkBuilder
won't be able to find it. So you are left with a few options.
mywidget_get_type()
somewhere early in your application. This will register the type in the GObject
type system and GtkBuilder
will be able to find it. I am using a subclass of GtkApplication
, so I'm calling it in my myapp_class_init
. This feels a little bit like a hack, but I settled on this solution because it seems like it should be portable to every situation.-rdynamic
. This will put all symbols in the dynamic symbol table so the magic described above will allow GtkBuilder
to find it.-rdynamic
works.