I am trying to measure the size of a GTK label:
#include <gtk/gtk.h>
static void map_event(GtkWidget *window, gpointer lab) {
g_print( "In the callback..\n" );
GtkWidget *label = GTK_WIDGET(lab);
g_print( "Everything is ok..\n" );
}
static void activate (GtkApplication* app, gpointer user_data)
{
GtkWidget *window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window1");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 280);
GtkWidget *grid = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window), grid);
GtkWidget *label = gtk_label_new("Hello world!");
gtk_grid_attach(GTK_GRID (grid), label, 0,0,1,1);
g_signal_connect (window, "map-event", G_CALLBACK(map_event), label);
gtk_widget_show_all (window);
}
int main (int argc, char **argv) {
GtkApplication *app = gtk_application_new (
"org.gtk.example", G_APPLICATION_FLAGS_NONE );
g_signal_connect( app, "activate", G_CALLBACK(activate), NULL);
int status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref (app);
return status;
}
This gives output:
In the callback..
Segmentation fault (core dumped)
If I comment out the line:
GtkWidget *label = GTK_WIDGET(lab);
there is no segmentation fault, the label shows up and the output is:
In the callback..
Everything is ok..
What am I missing here?
You don't respect the signal signature. Each signal is associated with a pre-defined function prototype you must respect, otherwise you'll just read garbage. Here you just made up out of your mind the callback signature so things won't work as expected.
The signal is like a delicious fruit delivery service. By connecting to that signal, you signed a contract that subscribe you to the fruit delivery service. Fruit will be delivered only when the fruit is ripe. The delivery man will:
The contract also specifies that:
Those boxes are like the arguments of your callback. The map-event takes 3 arguments, thus the 3 boxes.
One day, you hear knocking at the door. You open the door, see the boxes, open box #2 and get annoyed saying "damn, I said I wanted oranges!". The thing is that you're mixing apples and oranges: by contract, oranges are in box #3 and you're looking for them in box #2.
So give a look at the documentation of each signal you want to connect to. That's the only way to write the right callback. Here you forgot one input parameter as well as the return value. In the case of
map-event
, that return value can be seen as you going to the truck to say if you want to continue or stop the deliveries.map-event
has following signature, so you are missingGdkEvent*
argument:Unfortunately, GTK+ is written in C, so it lacks type-safe callback functions, so it's easy to make mistakes such as this.