Callback if a gtkwidget gets destroyed

Is it possible to have a callback if any widget get is getting destroyed.
In the following code, for example, I want the callback to be executed if spin button is getting destroyed.

#include <gtk/gtk.h>
#include <math.h>

gboolean destroy_callback( GtkWidget *spin_button, void *array )
{
	printf( "%s %d freeing: %p\n", __func__, __LINE__, array );
	free( array );
	return TRUE;
}

int main()
{
	gtk_init( NULL, NULL );
 	GtkWidget *const window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
 	gtk_window_set_default_size( GTK_WINDOW(window), 100, 100 );
 	g_signal_connect( window, "destroy", G_CALLBACK(gtk_main_quit), NULL );
 	GtkWidget *box = gtk_box_new( GTK_ORIENTATION_VERTICAL, 5 );
 
 	gtk_container_add( (GtkContainer*)window, box );
 	int *array = calloc( 10, 10 );
 	GtkWidget *spin = gtk_spin_button_new_with_range( 0, 255, 1 );
 	gtk_box_pack_start( (GtkBox*)box, spin, FALSE, FALSE, 5 );
 	if( g_signal_connect( G_OBJECT( box ), "delete-event", G_CALLBACK(destroy_callback), array ) == 0 )
 	{
 		fprintf( stderr, "%s %d Unable to connect", __func__, __LINE__ );
 		return 0;
 	}
 	gtk_widget_show_all( window );
 	gtk_main();
 	return 0;
 }

The GtkWidget::delete-event signal is only emitted on top levels, not widgets.

If you want to associate some data to a widget and free it when the widget is destroyed, you have two options:

  1. use the GtkWidget::destroy signal, connect a callback to it, and free the data; this is similar to what you did above
  2. use g_object_set_data_full() to store the data on the widget instance, and have it freed when the object is finalized, e.g.:
  // Your use of calloc() is wrong; the second argument is the size of each element
  int *int_array = calloc (10, sizeof (int));
  g_object_set_data_full (G_OBJECT (spin),
                          "spin-data-array",
                          int_array,
                          (GDestroyNotify) free);

you can retrieve the data pointer from the instance using g_object_get_data().

i have modified the code as follows:

#include <gtk/gtk.h>
#include <math.h>

gboolean destroy_callback( GtkWidget *widget, void *array )
{
printf( “%s %d freeing: %p\n”, __func__, __LINE__, array );
free( array );
return TRUE;
}

int main()
{
gtk_init( NULL, NULL );
GtkWidget *const window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_default_size( GTK_WINDOW(window), 100, 100 );
g_signal_connect( window, “destroy”, G_CALLBACK(gtk_main_quit), NULL );
GtkWidget *box = gtk_box_new( GTK_ORIENTATION_VERTICAL, 5 );

gtk_container_add( (GtkContainer*)window, box );
int *array = calloc( 10, sizeof(int) );
GtkWidget spin = gtk_spin_button_new_with_range( 0, 255, 1 );
gtk_box_pack_start( (GtkBox
)box, spin, FALSE, FALSE, 5 );
if( g_signal_connect( G_OBJECT( box ), “destory”, G_CALLBACK(destroy_callback), array ) == 0 )
{
fprintf( stderr, “%s %d Unable to connect\n”, __func__, __LINE__ );
return 0;
}
gtk_widget_show_all( window );
gtk_main();
return 0;
}

I am seeing error output :

$ gcc destroy.c `pkg-config --cflags --libs gtk±3.0 glib-2.0` && ./a.out

(a.out:13235): GLib-GObject-WARNING **: 10:04:52.312: …/…/…/gobject/gsignal.c:2617: signal ‘destory’ is invalid for instance ‘0x55fa2a7341a0’ of type ‘GtkBox’
main 25 Unable to connect

The signal is called “destroy”, not “destory “.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.