如何在GTK中获取按钮的文本?

问题描述 投票:4回答:2

我正在开发一个应用程序,当单击按钮时,该应用程序具有数字小键盘和文本框,文本框显示该数字。我需要为每个按钮编写一个函数吗?或者您可以将文本和小部件作为参数传递?

#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>

void callback( GtkWidget *widget,
               gpointer   data )
{
   gtk_entry_append_text(entry, text);
}

void create_button(GtkWidget* table,GtkWidget* entry,
                    int start_r,int end_r,
                    int start_c,int end_c,
                    char* label)
{
    GtkWidget *button;

    button = gtk_button_new_with_label (label);
    g_object_set_data( G_OBJECT( button ),
                           "char", (gpointer)label );
    g_signal_connect (button, "clicked",
              G_CALLBACK (callback), entry);

    gtk_table_attach_defaults (GTK_TABLE(table), button, start_c, end_c, start_r, end_r);

    gtk_widget_show (button);

}

gint delete_event( GtkWidget *widget,
                   GdkEvent  *event,
                   gpointer   data )
{
    gtk_main_quit ();
    return(FALSE);
}

int main(int argc,char* argv[]){

    GtkWidget *window;
    //GtkWidget *button;
    GtkWidget *table;
    GtkWidget *entry;
    //GtkWidget *label;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window), "Armario");
    g_signal_connect (GTK_OBJECT (window), "delete_event",
                        G_CALLBACK (delete_event), NULL);
    gtk_container_set_border_width (GTK_CONTAINER (window), 20);

    table = gtk_table_new (2, 2, TRUE);
    gtk_container_add (GTK_CONTAINER (window), table);

    entry = gtk_entry_new();
    gtk_entry_set_max_length(GTK_ENTRY(entry),10);
    gtk_entry_set_placeholder_text(GTK_ENTRY(entry),"Teste");
    gtk_table_attach_defaults (GTK_TABLE(table), entry, 0, 2, 1, 2);
    gtk_widget_show(entry);

    create_button(table,entry,0,1,0,1,"Botao");

    gtk_widget_show (table);
    gtk_widget_show (window);

    gtk_main ();

    return 0;
}
c gtk
2个回答
8
投票

您的问题的答案是肯定的,您可以将Gtk +中的小部件传递给回调。实际上,clicked信号回调的第一个参数是接收信号的按钮(即通常是点击的按钮)。正如您在下面的示例代码中所看到的,您可以从按钮中提取其标签并将其用作文本。

[...] /* In create_button... */
/* Make your buttons be notified when they are clicked */
g_signal_connect (button, "clicked", G_CALLBACK (on_button_clicked), entry);
[...]

/* Append the text in the button to the text entry */
void on_button_clicked (GtkButton *button, gpointer user_data)
{
    GtkEntry *entry = user_data;
    const gchar *text = gtk_button_get_label (button);
    gint position = 0;
    gtk_editable_insert_text (GTK_EDITABLE (entry), text, -1, &position);
}

我正在使用gtk_editable_insert_text,因为gtk_entry_append_text已经被弃用了很长时间。通过使用g_signal_connect的最后一个参数可以将“entry”参数传递给回调,该参数允许您指定需要在回调中访问的一些数据。然后,此信息可用于“user_data”参数中的回调。

你的例子也可以通过使用gtk_widget_show_all来改进,我也没有看到在“char”属性上调用g_object_set_data的重点,因为文本已经在label属性中设置(并使用gtk_button_get_label检索)。


1
投票

我能想到的两个选择:

  1. GTK小部件实际上是GObject,因此您可以将任意数据附加到它们。查看函数g_object_set_data/g_object_set_data_full/g_object_get_data。因此,您只需将文本作为附加数据添加到按钮,并在需要时检索它。
  2. 您可以通过定义包含所有字段的结构并将指针传递给它来将所需的任何数据传递给回调。如果结构不能静态声明,你可以malloc它并使用g_signal_connect_data指定释放数据的函数:

例如:

struct entry_and_text;
{
     GtkWidget *w;
     char *text;
};
void free_data(gpointer data, GClosure *closure)
{
     free(data);
}

entry_and_text *data = (entry_and_text *)malloc(sizeof(entry_and_text));
data->w = entry;
data->text = label;
g_signal_connect_data (button, "clicked",
          G_CALLBACK (callback), data, free_data, 0);
© www.soinside.com 2019 - 2024. All rights reserved.