Как получить текст кнопки в GTK? - PullRequest
4 голосов
/ 17 февраля 2012

Я разрабатываю приложение, которое имеет цифровую клавиатуру и текстовое поле при нажатии на кнопку, текстовое поле показывает номер.Мне нужно написать функцию для каждой кнопки?Или вы можете передать текст и виджет в качестве параметра?

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

Ответы [ 2 ]

8 голосов
/ 17 февраля 2012

Ответ на ваш вопрос: да, вы можете передать виджет в 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 уже давно устарел. Передача параметра "entry" в обратный вызов возможна с помощью последнего параметра g_signal_connect , который позволяет вам указать некоторые данные, к которым вам нужно получить доступ в вашем обратном вызове. Затем эта информация становится доступной для обратного вызова в параметре «user_data».

Ваш пример также может быть улучшен с помощью gtk_widget_show_all , и я также не вижу смысла в вызове g_object_set_data для свойства char, поскольку текст уже установлен в метке свойство (и извлекается с помощью gtk_button_get_label ).

1 голос
/ 17 февраля 2012

Два варианта, которые я могу придумать:

  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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...