2014-03-13 105 views
1

我試圖學習如何使用gtk + 3.0來製作GUI。我想將一個簡單的參數,一個整數,傳遞給一個回調函數,這樣當我按下按鈕時,參數的值就會改變。這裏是我的代碼:將其他參數傳遞給gtk函數

#include <gtk/gtk.h> 

void buttonFunction(GtkWidget * widget, gpointer data, int & n){ 
    n = 1; 
} 

int main(int argc, char ** argv){ 
    int n = 0; 
    GtkWidget * window; 
    GtkWidget * button; 

    gtk_init(&argc,&argv); 

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    button = gtk_button_new_with_label("Osss"); 

    gtk_container_add(GTK_CONTAINER(window),button); 
    gtk_widget_show_all(window); 

    g_signal_connect(G_OBJECT(window), "destroy",G_CALLBACK(gtk_main_quit), NULL); 
    g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(buttonFunction), n); 

    gtk_main(); 

    return 0; 
} 

我發現傳遞參數的唯一途徑是作爲一個指針:

void buttonFunction(GtkWidget * widget, gpointer * data); 
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(buttonFunction), &n); 

我如何傳遞多個參數這種方式壽?

+1

你的callbck參數是錯誤的:應該是'gpointer data'而不是'gpointer * data'。 'gpointer'已經是一個指針了,它是'void *'的一個typedef。 – liberforce

回答

3

要傳遞多個參數,你定義一個結構,填充它,和一個指針傳遞給上述結構的gpointer user_data參數g_signal_connect的,這是最後一個參數。然後在回調中,您只需將user_data參數投射到指向您的結構的指針。

int main (int argc, char **argv) 
{ 
    int n = 0; 
    GtkWidget *window; 
    GtkWidget *button; 

    gtk_init (&argc,&argv); 

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 
    button = gtk_button_new_with_label ("Osss"); 

    gtk_container_add (GTK_CONTAINER(window), button); 
    gtk_widget_show_all (window); 

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

    /* Here's the magic: you pass a pointer to the variable you'd like to modify 
    * in the callback, be it a simple variable or a struct */ 
    g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(buttonFunction), &n); 

    gtk_main(); 

    return 0; 
} 

void on_button_clicked (GtkButton *button, gpointer user_data) /* No extra parameter here ! */ 
{ 
    /* you cast to the type of what you passed as last argument of g_signal_connect */ 
    int *pn = user_data; 
    *pn = 1; 
} 

必須使用該文檔中定義回調的簽名(尋找的GtkButton文檔的「信號」一節),你不能做的事情了。順便說一句,你不能通過n作爲參考,而不是指針。如果您想在C++中使用GTK,請查看GTKmm。

3

有一堆有用的宏將一個整數(32位,不再是!)存儲到指針中。

int a = 42; 
gpointer ptr = GINT_TO_POINTER (a) 
//GUINT_TO_POINTER (a), GBOOLEAN_TO_POINTER (a), GSIZE_TO_POINTER (a) 

反向:

int a2 = GPOINTER_TO_INT (ptr); 
//GPOINTER_TO_UINT (ptr), GPOINTER_TO_...