将其他参数传递给gtk函数

时间:2014-03-13 16:05:45

标签: callback gtk gtk3

我正在尝试学习如何使用gtk + 3.0制作GUI。我想将一个简单的参数,一个整数传递给一个回调函数,这样当我按下按钮时,参数的值会发生变化。这是我的代码:

#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);

如何以这种方式传递多个参数?

3 个答案:

答案 0 :(得分:5)

要传递多个参数,您可以定义一个结构,填充它,并将指向结构的指针作为gpointer user_data的{​​{1}}参数传递,这是最后一个参数。然后在回调中,只需将g_signal_connect参数转换为指向结构的指针。

user_data

你必须使用文档中定义的回调签名(查看GtkButton文档的“信号”部分),你无法搞清楚。顺便说一句,你不能将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; } 作为参考而不是指针传递。如果你想在C ++中使用GTK,请看看GTKmm。

答案 1 :(得分:4)

有许多有用的宏可以将一个整数(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_...

答案 2 :(得分:0)

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

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

The above works perfectly fine to pass integer data thru g_signal_connect. Used as follows.

GtkWidget *Parison_ON_Buttons[10];

for (i=0; i < 8; i++)
{
    gpointer ONptr = GINT_TO_POINTER (i);
    g_signal_connect(GTK_SPIN_BUTTON(Parison_ON_Buttons[i]), "activate", G_CALLBACK 
    (Get_Parison_ON_Values),ONptr);
}

static gboolean Get_Parison_ON_Values (GtkSpinButton *button, gpointer data)
{
 int ONButtonNUmPressed = GPOINTER_TO_INT (data);
....
}