2010-12-05 2 views
1

J'ai l'exemple suivant de here, il l'indique sous le titre "Augmenter - Diminuer".Fonctions et signaux Gtk + Callback

#include <gtk/gtk.h> 

gint count = 0; 
char buf[5]; 

void increase(GtkWidget *widget, gpointer label) 
{ 
    count++; 

    sprintf(buf, "%d", count); 
    gtk_label_set_text(label, buf); 
} 

void decrease(GtkWidget *widget, gpointer label) 
{ 
    count--; 

    sprintf(buf, "%d", count); 
    gtk_label_set_text(label, buf); 
} 

int main(int argc, char** argv) { 

    GtkWidget *label; 
    GtkWidget *window; 
    GtkWidget *frame; 
    GtkWidget *plus; 
    GtkWidget *minus; 

    gtk_init(&argc, &argv); 

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); 
    gtk_window_set_default_size(GTK_WINDOW(window), 250, 180); 
    gtk_window_set_title(GTK_WINDOW(window), "+-"); 

    frame = gtk_fixed_new(); 
    gtk_container_add(GTK_CONTAINER(window), frame); 

    plus = gtk_button_new_with_label("+"); 
    gtk_widget_set_size_request(plus, 80, 35); 
    gtk_fixed_put(GTK_FIXED(frame), plus, 50, 20); 

    minus = gtk_button_new_with_label("-"); 
    gtk_widget_set_size_request(minus, 80, 35); 
    gtk_fixed_put(GTK_FIXED(frame), minus, 50, 80); 

    label = gtk_label_new("0"); 
    gtk_fixed_put(GTK_FIXED(frame), label, 190, 58); 

    gtk_widget_show_all(window); 

    g_signal_connect(window, "destroy", 
     G_CALLBACK (gtk_main_quit), NULL); 

    g_signal_connect(plus, "clicked", 
     G_CALLBACK(increase), label); 

    g_signal_connect(minus, "clicked", 
     G_CALLBACK(decrease), label); 

    gtk_main(); 

    return 0; 
} 

ce que je me demande est, la fonction g_signal_connect(plus, "clicked",G_CALLBACK(increase), label); envoie le « label » à l'augmentation de la fonction, où ses arguments sont void increase(GtkWidget *widget, gpointer label). Maintenant, dans la fonction d'augmentation, la fonction gtk_label_set_text() requiert un type de données GtkLabel comme premier argument, mais je ne vois qu'une variable GtkWidget et un pointeur vide label comme arguments de la fonction d'augmentation. Si c'est le cas, comment fonctionne gtk_label_set_text()?

Répondre

3

En C (mais et non C++), vous pouvez implicitement transformer un void* en pointeur vers un autre type. Il est très souvent vu lors de l'allocation mémoire avec malloc, qui renvoie une void*:

int *myIntArray = malloc(10 * sizeof(int)); // allocate array of 10 ints 

Votre code est en train de faire la même chose, juste avec le passage de paramètres:

void gtk_label_set_text(GtkLabel *label, const char *text); 
void *label = ...; 
gtk_label_set_text(label, "some string"); // label is implicitly cast from 
              // void* to GtkLabel* 
+0

Merci, une autre chose, pourquoi devrions-nous inclure le 'GtkWidget * widget' dans la fonction d'augmentation ?. – silent

+0

@ sil3nt: 'GtkWidget * widget' est inclus dans la fonction car la fonction doit avoir un prototype très spécifique. Le rappel 'GtkButton :: clicked' nécessite la fonction de rappel pour avoir cette signature et il vous passera un' GtkWidget * 'comme premier paramètre. Si votre rappel a la mauvaise signature, vous recevrez les mauvais paramètres et vous risquez de tomber en panne. –

+0

Donc le premier paramètre de la fonction d'augmentation est passé automatiquement par 'g_signal_connect (plus," clicked ", G_CALLBACK (augmentation), label);'? – silent