csignalsgtk3gtkbuilder

Signal 'show' not emitted from GUI constructed with GtkBuilder?


I am trying to initialize a GtkEntry widget from GSettings, through a signal handler for the 'show' signal. This works as expected when manually building the user interface, but fails to work when using GtkBuilder. The same applies to other GtkWidget signals; GtkEntry signals work as expected. It looks like the signal is never emitted?

#include <gtk/gtk.h>


void activated (GtkEntry *entry,
               gpointer  user_data){

    GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(user_data), GTK_DIALOG_DESTROY_WITH_PARENT,
                                               GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
                                               gtk_entry_get_text(entry));
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);

}



void shown (GtkWidget *widget,
               gpointer   user_data){
    GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(user_data), GTK_DIALOG_DESTROY_WITH_PARENT,
                                               GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
                                               "SHOWN!");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);

}



int main(int argc, char **argv){
    GtkWidget *window1, *window2, *entry;
    GtkBuilder *builder;


    gtk_init(&argc, &argv);

    // Construct working window 1

    window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window1),"Working");
    entry=gtk_entry_new();

    g_signal_connect(entry, "activate", G_CALLBACK(activated), window1);
    g_signal_connect(entry, "show", G_CALLBACK(shown), window1);

    gtk_container_add(GTK_WINDOW(window1), entry);


    // Construct not working window 2

    builder=gtk_builder_new_from_file ("window.glade");
    window2 = GTK_WIDGET(gtk_builder_get_object(builder, "window2"));
    gtk_builder_connect_signals(builder, NULL);
    g_object_unref(builder);


    gtk_widget_show_all(window1);
    gtk_widget_show_all(window2);


    gtk_main();

    return 0;
}

window.glade:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
  <requires lib="gtk+" version="3.12"/>
  <object class="GtkWindow" id="window2">
    <property name="can_focus">False</property>
    <property name="title" translatable="yes">Not working</property>
    <child>
      <object class="GtkEntry" id="entry1">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="shadow_type">none</property>
        <signal name="activate" handler="activated" object="window2" swapped="no"/>
        <signal name="show" handler="shown" object="window2" swapped="no"/>
      </object>
    </child>
  </object>
</interface>

Solution

  • Set the visible flag in GLADE to false (untick) so that when GtkBuilder instantiates the glade file contents, the widget isn't shown; then when you do gtk_widget_show_all for window2, the signal will get emmited.

    enter image description here

    Alternatively, edit window.glade and set the visible property to False or remove it (I think that by default the widget isn't visible), eg:

     ...
     <object class="GtkEntry" id="entry1">
        <property name="visible">False</property>
     ...