Autoconnecting signals in GTK4

,

Hi there, I am currently trying to adapt the GTK4 Hello World program to use GTK Builder. I have made the .ui file and imported it however when running the program I get the error “failed to add UI from file: No function named print_hello”. From reading documentation it seems like it may be an issue with the current object set however I am unsure what that should be.

#include <gtk-4.0/gtk/gtk.h>

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

static void activate(GtkApplication *app, gpointer user_data) {
  GError *error = NULL;
  GtkBuilder *builder;

  GtkWindow *window;
  GtkButton *button;

  builder = gtk_builder_new();

  gtk_builder_set_current_object(builder, G_OBJECT(app));

  if (!gtk_builder_add_from_file(builder, "application.ui", &error))
    g_error("failed to add UI from file: %s", error->message);

  window = GTK_WINDOW(gtk_builder_get_object(builder, "window"));
  gtk_application_add_window(app, window);

  gtk_window_present(window);
}

int main(int argc, char **argv) {
  GtkApplication *app;
  int status;

  app = gtk_application_new("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
  g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
  status = g_application_run(G_APPLICATION(app), argc, argv);
  g_object_unref(app);

  return status;
}
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.96.1 -->
<interface>
  <requires lib="gtk" version="4.12"/>
  <object class="GtkApplicationWindow" id="window">
    <property name="default-height">200</property>
    <property name="default-width">200</property>
    <property name="title">Hello</property>
    <child>
      <object class="GtkButton" id="button">
        <property name="label">Hello World</property>
        <signal name="clicked" handler="print_hello" object="button"/>
      </object>
    </child>
  </object>
</interface>

I am using the following command to compile: gcc $(pkg-config --cflags gtk4 gmodule-export-2.0) -Wl,--export-dynamic -o hello-world-gtk main.c $(pkg-config --libs gtk4 gmodule-export-2.0)

I have tried using gtk_builder_new_from_file but that has the same error.

Assistance would be much appreciated, if there is any additional information required I am happy to provide it.

Hi,

From reading documentation it seems like it may be an issue with the current object set however I am unsure what that should be.

no, you shouldn’t have to call gtk_builder_set_current_object. But you should expose the function to the builder using gtk_builder_cscope_add_callback, like so:

  GtkBuilderScope *scope;

  scope = gtk_builder_get_scope(builder);
  gtk_builder_cscope_add_callback(scope, print_hello);

With these lines added, your application runs, and prints “Hello world” when the button is clicked.

Please note that a more modern way to structure your application & use GtkBuilder is through composite widget templates. In that case, you’d expose callbacks using gtk_widget_class_bind_template_callback instead. Please let me know if you’d like an example of that.

2 Likes

Thank you very much for your assistance, I understand how it works much better now. I am fairly confident that I can get the template binding to work and there seems to much more information available for them.