2012-04-23 13 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コールバック多重引数

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構造体を使用する必要がありますか?それは良い方法ですか? – polslinux

+1

ええ、コールバックに渡す値が複数ある場合は、構造体へのポインタをg_signal_connectの最後のパラメータとして使用してください。コールバックのプロトタイプは、対応するシグナルのプロトタイプに常に従わなければなりません。これは、[[clicked](http://developer.gnome.org/gtk3/stable/GtkButton.html#GtkButton-clicked) "のシグナルのものです。 – liberforce

答えて

3

GTKはイベントドリブンのツールキットです(他の多くのものと同様)。イベントと対話する必要がありますが、 gtk_mainを実行するまでイベントをチェックしないでください。問題は、あなたがtest.host = gtk_entry_get_text(GTK_ENTRY (h_name))が、その時点でウィジェットは表示されておらず、あなたは何も入力していませんでした!したがって、基本的にはこれからヌル文字列を取得するだけで、「接続」ボタンをクリックすると表示されます。

これを行う1つの方法は、構造体のウィジェットへのポインタを持つことです。こうすることで、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も間違っています。テストは構造体です。&テストは構造体のアドレスです。 gpointerはvoid *です。すでにポインタなので、gpointer *はポインタへのポインタです。これは&テストではありません。だから&testと書いてください。

+0

ありがとう、あなたは非常に徹底していました!:) – polslinux

+0

もっと徹底的に信号とイベントを勉強すればいいです:)もう、ありがとう:) – polslinux

関連する問題