Search code examples
cmacosgtkglade

C - GTKUibuilder - Glade - g_signal_connect error


I am trying to use Glade on my project to generate a file containing windows, grid ... But I am stuck wth an error when I try to listen to event clicked on my buttons, I do not understand why :s

I got those errors..

 GLib-GObject-WARNING **: invalid (NULL) pointer instance

(test:5608): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

... for each listener.

So my file called "project_ui.ui" set in the same directory as my main.c :

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <child>
      <object class="GtkGrid">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkButton">
            <property name="label" translatable="yes">Button 1</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
          </object>
          <packing>
            <property name="left_attach">1</property>
            <property name="top_attach">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton">
            <property name="label" translatable="yes">Button 2</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
          </object>
          <packing>
            <property name="left_attach">2</property>
            <property name="top_attach">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton">
            <property name="label" translatable="yes">Button 0</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
          </object>
          <packing>
            <property name="left_attach">0</property>
            <property name="top_attach">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton">
            <property name="label" translatable="yes">Quit</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
          </object>
          <packing>
            <property name="left_attach">0</property>
            <property name="top_attach">1</property>
            <property name="width">3</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

My main.c contain this code:

#include <stdio.h>
#include <gtk-3.0/gtk/gtk.h>


static void printHello (GtkWidget *widget, gpointer data){
  g_print("Hello World \n");
}

int main(int argc, char *argv[]) {
  GtkBuilder *builder;
  GObject *window;
  GObject *button;

  gtk_init(&argc,&argv);

  builder = gtk_builder_new();
  gtk_builder_add_from_file(builder, "project_ui.ui", NULL);

  window = gtk_builder_get_object(builder, "window");
  g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

  //Button 1
  button = gtk_builder_get_object(builder, "Button 1");
  g_signal_connect(button, "clicked", G_CALLBACK(printHello), NULL);

  //Button 2
  button = gtk_builder_get_object(builder, "Button 2");
  g_signal_connect(button, "clicked", G_CALLBACK(printHello), NULL);

  //Button 0
  button = gtk_builder_get_object(builder, "Button 0");
  g_signal_connect(button, "clicked", G_CALLBACK(printHello), NULL);

  //button Quit
  button = gtk_builder_get_object(builder, "Quit");
  g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_widget_destroy), window);

  gtk_main();
  return 0;
}

Is someone has any idea to correct it ?


Solution

  • I tried it with my Ubuntu machine with Gtk 3.18.

    When I load your file in Glade I don't get any message in the UI but I get error messages on the shell:

    (glade:2996): GladeUI-WARNING **: The file did not contain the required property "id" Under the "object" tag.

    This is a good hint. If you look in your example that you linked, you find this:

    <object id="button2" class="GtkButton">
    

    You only have this:

    <object class="GtkButton">
    

    Without the ID the gtk_builder does not know how to find this widget.

    Because you use wrong value for searching your widgets:

    button = gtk_builder_get_object(builder, "Button 1");
    

    This is only the text shown on the button. What you need to use is the id which is missing. The example uses this code:

    button = gtk_builder_get_object (builder, "button1");
    

    Here the ID is used to retrieve the pointer to the widget.

    To solve your problem you need to add IDs to your widgets and use the IDs to retrieve them instead of the text on the label.