2
#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; } 

What is wrong whit this??
i have no errors and no warnings but on the terminal this program doesn't write anything :(
if i write:

test.host="trying something" 

it works but with gtk_entry_get_text it doesn't show nothing :(
i don't understand...why it doesn't work with gtk_entry_get_text?

4
  • It's true, you can't do this in C. This question is already answered here: stackoverflow.com/questions/6684466/… Commented Apr 23, 2012 at 11:40
  • ok thanks...so i have to use typedef struct?? It is the better way?? Commented Apr 23, 2012 at 12:01
  • 1
    Yeah, use a pointer to a struct as the last parameter of g_signal_connect if you have multiple values to pass to your callback. You callback's prototype must always follow the one for the corresponding signal. Here is the one for the "clicked" signal. Commented Apr 23, 2012 at 12:24
  • i have updated my code..could you please checking what is wrong?? :( thanks Commented Apr 23, 2012 at 12:33

1 Answer 1

4

You need to understand that GTK is an event-driven toolkit (like many other). You need interact with events. But it won't check for events until you've run gtk_main. So your problem is that you're reading the hostname using test.host = gtk_entry_get_text(GTK_ENTRY (h_name)), but at that time, the widget hasn't been displayed, and you didn't even typed anything in it! So you're basically just getting a null string from this, and that is what you display when you click on the "connect" button.

One way to do it is to have your pointer to widgets in the struct. That way, you call gtk_entry_get_text from inside the b_clicked callback. That way, the value you get is the one that is inside the text entry widget at that time.

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

Another nicer way to do it is, without modifying your struct, is to ask to be notified when the text has changed. For that, use the "changed" signal, as GtkEntry implements the GtkEditable interface. See "GtkEntry text change signal".

Please also note that (gpointer*)&test is wrong. test is a struct, &test is the adress of a struct. gpointer is a void *, ie. already a pointer, so gpointer * is a pointer to a pointer, which is not what &test is. So just write &test.

Sign up to request clarification or add additional context in comments.

1 Comment

now it's better if I study more thoroughly the signals and the events :) again, thanks :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.