Home > Mobile >  why is this gtk code failing to load ui file properly?
why is this gtk code failing to load ui file properly?

Time:10-18

In the gtk4 documentation there is an example where the function gtk_builder_add_from_file is used to load a builder.ui file, I used the same code but I create the builder.ui using glade application, when I compile and run the program I don't get anything inside the window but the title is the same one I defined in the glade app

Here is the contents of the builder.ui

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
  <requires lib="gtk " version="3.24"/>
  <object  id="MainWindow">
    <property name="can-focus">False</property>
    <property name="title" translatable="yes">MyApp</property>
    <property name="default-width">440</property>
    <property name="default-height">250</property>
    <signal name="destroy" handler="exit_app" swapped="no"/>
    <child>
      <object >
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <placeholder/>
        </child>
        <child>
          <object  id="Button">
            <property name="label" translatable="yes">button</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

and this is the code I am using to load the file

#include <gtk/gtk.h>
#include <glib/gstdio.h>

static void print_hello(GtkWindow * window, gpointer data)
{
    g_print("Clicked");
}

// renders the application
static void activate(GtkApplication * app, gpointer * user_data)
{
    /* Construct a GtkBuilder instance and load our UI description */
    GtkBuilder *builder = gtk_builder_new ();
    gtk_builder_add_from_file (builder, "builder.ui", NULL);

    // connect signal handlers to the constructed widgets
    GObject * window = gtk_builder_get_object(builder,"MainWindow");
    gtk_window_set_application(GTK_WINDOW(window), app);


    gtk_widget_show(GTK_WIDGET(window));

    // unload the builder (destroy)
    g_object_unref(builder);

}


int main(int argc, char ** argv)
{

    #ifdef GTK_SCRDIR
        g_chdir(GTK_SCRDIR);
    #endif

    GtkApplication * app = gtk_application_new("org.gtk.application", G_APPLICATION_FLAGS_NONE);
    g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);

    int status = g_application_run(G_APPLICATION(app), argc, argv);

    g_object_unref(app);

    return status;
}

it compiles fine and runs with out any errors but no button what so ever is shown inside the window

CodePudding user response:

That's because you are using GTK3 builder UI code which may not be valid in GTK4. For the given builder.ui file, GtkBox child properties have been removed in GTK4. See relevant section from docs.

So, removing <packing> ... </packing> should be enough for your code.

Alternately, you can use gtk4-builder-tool to convert your GTK3 UI definitions to GTK4 by running gtk4-builder-tool simplify --3to4 --replace builder.ui (Remove --replace flag to print the output to stdout without replacing the input file)

which gives the following output for your file:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <object  id="MainWindow">
    <property name="title" translatable="1">MyApp</property>
    <property name="default-width">440</property>
    <property name="default-height">250</property>
    <signal name="destroy" handler="exit_app" swapped="no"/>
    <property name="child">
      <object >
        <property name="orientation">vertical</property>
        <child>
          <placeholder/>
        </child>
        <child>
          <object  id="Button">
            <property name="label" translatable="1">button</property>
            <property name="focusable">1</property>
            <property name="receives-default">1</property>
          </object>
        </child>
      </object>
    </property>
  </object>
</interface>
  • Related