2012-04-23 2 views
1
#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 callback несколько аргументов

test.host="trying something" 

он работает, но с gtk_entry_get_text он не показывает ничего :(
Я не понимаю ... почему это не работает с gtk_entry_get_text?

+0

Это правда, вы не можете сделать это в C. На этот вопрос уже ответили: http://stackoverflow.com/questions/6684466/c-passing-multiple-arguments-to-a-callback-function- in-gtk – ptomato

+0

ok спасибо ... так что я должен использовать typedef struct ?? Это лучший способ? – polslinux

+1

Да, используйте указатель на структуру в качестве последнего параметра g_signal_connect, если у вас есть несколько значений для передачи обратного вызова. Прототип обратного вызова должен всегда следовать за сигналом соответствующего сигнала. Вот один из сигналов «[clicked] (http://developer.gnome.org/gtk3/stable/GtkButton.html#GtkButton-clicked)». – liberforce

ответ

3

Вы должны понимать, что GTK - это инструментарий, управляемый событиями (как и многие другие). Вам нужно взаимодействовать с событиями, t проверить события до тех пор, пока вы не запустите gtk_main. Поэтому ваша проблема заключается в том, что вы читаете имя хоста, используя test.host = gtk_entry_get_text(GTK_ENTRY (h_name)), но в то время виджет не был отображен, и вы даже не написали ничего в нем! Таким образом, вы просто получаете пустую строку, и именно это вы показываете, когда вы нажимаете кнопку «подключиться».

Один из способов сделать это - указать указатель на виджетов в структуре. Таким образом, вы вызываете gtk_entry_get_text из обратного вызова b_clicked. Таким образом, вы получите то, что находится внутри виджета ввода текста в то время.

#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 является неправильным. test - это struct, & test - это адрес структуры. gpointer - это пустота *, т.е. уже указатель, поэтому gpointer * является указателем на указатель, который не является чем-то & тестом. Так что просто напишите &test.

+0

спасибо большое, вы были очень основательны! :) – polslinux

+0

теперь лучше, если я более подробно изучу сигналы и события :), спасибо :) – polslinux

Смежные вопросы