Home > Mobile >  gtk_widget_destroy: assertion 'GTK_IS_WIDGET (widget)' failed
gtk_widget_destroy: assertion 'GTK_IS_WIDGET (widget)' failed

Time:06-06

I have GTK GUI where it has a control button that opens a new window called c_window in my struct. c_window has a quit button that I need to connect to the c_quit function. When I tried to do so the window is not terminated and a warning keeps appearing each time I pressed on quit button:

(main_menu:2682): Gtk-CRITICAL **: 06:30:38.469: gtk_widget_destroy: assertion 'GTK_IS_WIDGET (widget)' failed

my c_quit function is:

    static gboolean c_quit (gpointer userData)
    {
    message_details *details = (message_details *)userData;
    gtk_widget_destroy (details->c_window); 
    return FALSE;
    }

how do I connect it from the main

g_signal_connect(G_OBJECT(details->c_quit), "clicked", G_CALLBACK (c_quit),  details->c_window);

Please note that details is my struct where I define my GtkWidget elements.

CodePudding user response:

First of all, your signal connection function is:

g_signal_connect(G_OBJECT(details->c_quit), "clicked", G_CALLBACK (c_quit),  details->c_window);

Which contains an unnecessary cast for details->c_quit. Additionally, you're passing the c_window field of the details pointer.

Next, your callback is:

static gboolean c_quit (gpointer userData)
{
  message_details *details = (message_details *)userData;
  gtk_widget_destroy (details->c_window); 
  return FALSE;
}

which has the wrong signature for a callback to the GtkButton::clicked signal; the correct signature would be:

static void
c_quit (GtkButton *button, gpointer data)

Additionally, I'd recommend using a proper function name for the callback, so you can easily understand what it does, and where it's referenced. For instance, something quit_button__clicked.

Inside your callback you're accessing the wrong parameter, with the wrong type:

message_details *details = (message_details *)userData;

Because you're not passing the details data, you're passing a pointer to the window itself. Additionally, gpointer is an alias to void*, and C allows implicit casting to and from a void*; this means you don't need an explicit cast there.

So, to recap:

  1. connect the signal properly, using the correct arguments to send to your callback:
g_signal_connect (details->c_quit, "clicked",
                  G_CALLBACK (quit_button__clicked),
                  details);
  1. use the right prototype for the signal you're connecting to, and access the right data:
static void
quit_button__clicked (GtkButton *button G_GNUC_UNUSED,
                      gpointer user_data)
{
  message_details *details = user_data;
  gtk_widget_destroy (details->c_window);
}

If you just want to call gtk_widget_destroy() on the window widget in response to a clicked signal on a GtkButton, you can also condense everything into a single call:

g_signal_connect_swapped (details->c_quit, "clicked",
                          G_CALLBACK (gtk_widget_destroy),
                          details->c_window);

The g_signal_connect_swapped() function will swap the first and last arguments of the signal when invoking the callback—the first argument being the instance that emitted the signal, and the last argument being the user data passed to connection function. This means that gtk_widget_destroy() will be called with the user data argument of g_signal_connect_swapped().

  • Related