gtk回调多个参数 [英] gtk callback multiple arguments

查看:156
本文介绍了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;
}

这是什么错误?

i没有错误和没有警告,但在终端此程序不会写任何东西:(

如果我写:

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"

它可以工作,但使用gtk_entry_get_text时, t什么都不显示:(


i不明白...为什么它不能和gtk_entry_get_text一起工作?

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?

推荐答案

你需要明白GTK是一个事件驱动的工具包(就像许多其他的一样),你需要与事件交互,但在你运行gtk_main之前它不会检查事件,所以你的问题是你使用 test.host = gtk_entry_get_text(GTK_ENTRY(h_name))读取主机名,但是那时候,这个小部件还没有显示出来,甚至没有输入任何东西在它!所以你基本上只是从这里得到一个空字符串,这就是你点击连接对接时显示的对接on。

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.

执行此操作的一种方法是将指针指向结构中的小部件。这样,您可以从b_clicked回调中调用gtk_entry_get_text。这样,您获得的价值就是当时文本输入窗口小部件中的一个

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

另一个更好的方法是在不修改你的结构的情况下,在文本发生变化时收到通知。为此,请使用更改信号,因为GtkEntry实现GtkEditable接口。请参阅 GtkEntry文本更改信号

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".

请注意,(gpointer *)& test 是错误的。 test是一个结构体,& test是结构体的地址。 gpointer是一个void *,即。已经是一个指针了,所以 gpointer * 是一个指向指针的指针,这不是什么& test。所以只要写& test

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.

这篇关于gtk回调多个参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆