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

これは何が悪いのですか??
エラーも警告もありませんが、端末ではこのプログラムは何も書きません
:(

test.host="trying something"

動作しますが、gtk_entry_get_text では何も表示されません :(
わかりません...なぜ gtk_entry_get_text で動作しないのですか?

4

1 に答える 1

4

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

これを行う 1 つの方法は、構造体にウィジェットへのポインターを配置することです。そうすれば、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;
}

もう 1 つの良い方法は、構造体を変更せずに、テキストが変更されたときに通知を受け取るように依頼することです。そのためには、GtkEntry が GtkEditable インターフェースを実装しているため、「 changed 」シグナルを使用します。GtkEntry テキスト変更シグナル」を参照してください。

間違いもありますのでご注意ください(gpointer*)&test。test は構造体で、&test は構造体のアドレスです。gpointer は void * です。すでにポインターであるためgpointer *、ポインターへのポインターであり、&test とは異なります。だからただ書いて&testください。

于 2012-04-23T13:12:46.557 に答える