gtk回调多个参数
问题描述:
#include <gtk/gtk.h>
#include <stdio.h>
typedef struct {
const gchar *host;
} example;
void b_clicked (GtkButton *c_button, example *test){
g_print("Hostname: %s\n", test->host);
}
int main (int argc, char *argv[]){
GtkWidget *window;
GtkWidget *grid;
GtkWidget *c_button;
GtkWidget *q_button;
GtkWidget *label_host;
GtkWidget *h_name;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "FTP Client");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
grid = gtk_grid_new();
gtk_container_add (GTK_CONTAINER (window), grid);
gtk_grid_set_row_spacing (GTK_GRID (grid), 3);
label_host = gtk_label_new("Hostname");
example test;
h_name = gtk_entry_new();
test.host = gtk_entry_get_text(GTK_ENTRY (h_name));
gtk_entry_set_placeholder_text (GTK_ENTRY (h_name), "Hostname");
c_button = gtk_button_new_with_label ("Connect");
g_signal_connect (c_button, "clicked", G_CALLBACK (b_clicked), (gpointer*)&test);
q_button = gtk_button_new_with_label ("Quit");
g_signal_connect (q_button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
gtk_grid_attach (GTK_GRID (grid), label_host, 0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid), h_name, 1, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid), c_button, 0, 3, 2, 1);
gtk_grid_attach (GTK_GRID (grid), q_button, 0, 4, 2, 1);
gtk_widget_show_all (window);
gtk_main();
return 0;
}
这是什么问题?
我没有错误,没有警告,但在终端上,该程序不能写什么:(
如果我写:
gtk回调多个参数
test.host="trying something"
它的工作原理但gtk_entry_get_text它并没有显示什么:(
我不明白...为什么它不适用于gtk_entry_get_text?
答
你需要明白,GTK是一个事件驱动的工具包(就像其他很多),你需要与事件交互,但它赢得了'在你运行gtk_main之前检查事件,所以你的问题是你正在使用主机名test.host = gtk_entry_get_text(GTK_ENTRY (h_name))
,但那时候,小部件还没有显示出来,甚至没有输入任何东西!所以你基本上只是从中得到一个空字符串,这就是你点击“连接”按钮时显示的内容。
做到这一点的一种方法是将指针指向结构中的小部件。这样,您可以从b_clicked回调中调用gtk_entry_get_text。这样,您获得的价值就是那个文本条目窗口小部件当时的价格。
#include <gtk/gtk.h>
#include <stdio.h>
typedef struct {
GtkWidget *host;
} example;
void b_clicked (GtkButton *c_button, example *test){
g_print("Hostname: %s\n", gtk_entry_get_text (GTK_ENTRY(test->host)));
}
int main (int argc, char *argv[]){
GtkWidget *window;
GtkWidget *grid;
GtkWidget *c_button;
GtkWidget *q_button;
GtkWidget *label_host;
GtkWidget *h_name;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "FTP Client");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
grid = gtk_grid_new();
gtk_container_add (GTK_CONTAINER (window), grid);
gtk_grid_set_row_spacing (GTK_GRID (grid), 3);
label_host = gtk_label_new("Hostname");
example test;
h_name = gtk_entry_new();
test.host = h_name;
gtk_entry_set_placeholder_text (GTK_ENTRY (h_name), "Hostname");
c_button = gtk_button_new_with_label ("Connect");
g_signal_connect (c_button, "clicked", G_CALLBACK (b_clicked), &test);
q_button = gtk_button_new_with_label ("Quit");
g_signal_connect (q_button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
gtk_grid_attach (GTK_GRID (grid), label_host, 0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid), h_name, 1, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid), c_button, 0, 3, 2, 1);
gtk_grid_attach (GTK_GRID (grid), q_button, 0, 4, 2, 1);
gtk_widget_show_all (window);
gtk_main();
return 0;
}
另一种更好的方式来做到这一点,不修改你的结构,是要求在文本发生变化时得到通知。为此,请使用“changed”信号,因为GtkEntry实现了GtkEditable接口。参见“GtkEntry text change signal”。
请注意,(gpointer*)&test
是错误的。测试是一个结构,&测试是结构的地址。 gpointer是一个void *,即。已经是一个指针了,所以gpointer *
是一个指向指针的指针,这不是&测试的结果。所以只需写&test
。
这是真的,你不能在C中做到这一点。这个问题已经在这里解答:http://stackoverflow.com/questions/6684466/c-passing-multiple-arguments-to-a-callback-function- in-gtk – ptomato 2012-04-23 11:40:17
好的谢谢...所以我必须使用typedef结构?这是更好的方法? – polslinux 2012-04-23 12:01:16
是的,如果你有多个值传递给你的回调函数,那么使用指向struct的指针作为g_signal_connect的最后一个参数。您回调的原型必须始终遵循相应信号的原型。这里是“[clicked]”(http://developer.gnome.org/gtk3/stable/GtkButton.html#GtkButton-clicked)“信号。 – liberforce 2012-04-23 12:24:58