Loading a file with gtk_builder_new_from_resource

I am not really a fan of GtkBuilder, but I decided to give it a try.
Every thing works fine till gtk_builder_new_from_resource()

How does this function works? I am getting:

> Gtk-ERROR **: 13:56:31.117: failed to add UI: The resource at “/home/michi/Templates/GtkBuilder/resource.xml” does not exist
Trace/breakpoint trap (core dumped)

What I have so far:
main.c:

#include <gtk/gtk.h>

G_MODULE_EXPORT void clicked_clbk ( GtkWidget *button, G_GNUC_UNUSED gpointer data );
G_MODULE_EXPORT void clicked_clbk ( GtkWidget *button, G_GNUC_UNUSED gpointer data )
{
    g_return_if_fail ( GTK_IS_BUTTON ( button ) );

    /// ***
    g_print ( "Hallo, World!\n" );
}

static void connection_mapper ( G_GNUC_UNUSED GtkBuilder *builder,
                                GObject *object,
                                const gchar *const signal_name,
                                const gchar *const handler_name,
                                G_GNUC_UNUSED GObject *connect_object,
                                G_GNUC_UNUSED GConnectFlags flags,
                                G_GNUC_UNUSED gpointer user_data )
{
    const gchar* const object_name =  gtk_widget_get_name ( GTK_WIDGET ( object ) );
    g_print ( "Connecting the '%s' Signal to the '%s' object with the '%s' Objects\n", signal_name, object_name, handler_name );

    if ( g_strcmp0 ( handler_name, "gtk_main_quit" ) == 0 )
    {
        g_signal_connect ( object, signal_name, G_CALLBACK ( gtk_main_quit ), NULL );
    }

    else if ( g_strcmp0 ( handler_name, "clicked_clbk" ) == 0 )
    {
        g_signal_connect ( object, signal_name, G_CALLBACK ( clicked_clbk ), NULL );
    }

    else
    {
        g_print ( "Wrong Callback\n" );
    }

}

int main ( void )
{
    GtkWidget  *window;
    GtkBuilder *builder;

    /// ***
    gtk_init ( NULL, NULL );

    /// ***
    builder = gtk_builder_new_from_resource ( "resources.ui" );

    /// ***
    window = GTK_WIDGET ( gtk_builder_get_object ( builder, "main-window" ) );

    /// ***
    gtk_builder_connect_signals_full ( builder, connection_mapper, NULL );

    /// ***
    gtk_widget_show_all ( window );
    gtk_main ();
}

gresources.xml:

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
    <gresource prefix="/main">
        <file compressed="true">resources.ui</file>
    </gresource>
</gresources>

resources.ui:

<interface>

    <object class="GtkWindow" id="main-window">
       <property name="window-position">GTK_WIN_POS_CENTER</property>
       <property name="title">GtkBuildable-Demo</property>
       <property name="type">GTK_WINDOW_TOPLEVEL</property>
       <property name="default-width">250</property>
       <property name="default-height">250</property>
       <property name="border-width">8</property>
       <signal name="destroy" handler="gtk_main_quit"/>

       <child>
           <object class="GtkButton" id="click-button">
               <property name="label"> Click </property>
               <property name="margin"> 50 </property>
               <signal name="clicked" handler="clicked_clbk"/>
           </object>
       </child> /// End Button

    </object> /// End Window

</interface> /// End Interface

And from terminal:

glib-compile-resources gresources.xml  --generate-source --target=gresources.c
glib-compile-resources gresources.xml  --generate-header --target=gresources.h

and got the two files gresources.c and gresources.h.

What should I do next?

First of all: you register the resource as:

Which means the resource path is /main/resources.ui; this means you will need to fix this line:

to load /main/resources.ui.

You need to compile gresources.c with your own program; then you will need to include gresources.h in your main.c file, and in your main function, after calling gtk_init(), you will need to call the register_resource function declared in the header.

In general, it’s recommended you should use something like --c-name=some_prefix in the invocation of glib-compile-resources, to prefix the symbols generated by the tool. Or, better yet, use a build system like Meson, instead of manually calling stuff yourself; Meson has a whole function to shield you from all this gunk.

2 Likes

You are everything what a programmer needs :slight_smile:. Works like a charm.

Yes, but I wanted to know how this one works.
Thank you for your time.

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