Проблема с g_signal_connect, g_cclosure_new, gpointer

// gcc 1.c -o 0 $(pkg-config --cflags --libs gtk+-2.0)
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
struct tst
{
    GtkWidget *win, *vb, *ent, *btn, *lbl;
    GtkAccelGroup *acc;
    GClosure *cls;
};
static void print_val(int nmb)
{
    g_printf("%d\n", nmb);
}
static void window_new()
{
    struct tst *prg = g_new0(struct tst, 1);
    prg->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    prg->vb = gtk_vbox_new(TRUE, 0);
    prg->ent = gtk_entry_new();
    prg->btn = gtk_button_new_with_label("Print!");
    prg->lbl = gtk_label_new("Enter the string.");
    prg->acc = gtk_accel_group_new();
    int nmb = 140;
    prg->cls = g_cclosure_new(G_CALLBACK(print_val), nmb, NULL);
    gtk_container_add(GTK_CONTAINER(prg->win), GTK_WIDGET(prg->vb));
    gtk_box_pack_start(GTK_BOX(prg->vb), GTK_WIDGET(prg->ent), FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(prg->vb), GTK_WIDGET(prg->btn), FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(prg->vb), GTK_WIDGET(prg->lbl), FALSE, FALSE, 0);
    g_signal_connect(prg->win, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    g_signal_connect(prg->btn, "clicked", G_CALLBACK(print_val), (gpointer)nmb);
    gtk_window_set_title(GTK_WINDOW(prg->win), "Enter the string");
    gtk_window_add_accel_group(GTK_WINDOW(prg->win), prg->acc);
    gtk_accel_group_connect(prg->acc, GDK_KEY_P, (GDK_CONTROL_MASK | GDK_SHIFT_MASK), GTK_ACCEL_MASK, prg->cls);
    gtk_widget_show_all(GTK_WIDGET(prg->win));
}
int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
    window_new();
    gtk_main();
    return 0;
}

Я хочу, чтобы эта программа печатала 140 на консоли каждый раз, когда я нажимал кнопку или Ctrl + Shift + P.

Но эта программа печатает странное значение (не 140), когда я нажимаю кнопку или Ctrl + Shirt + P.

Что я должен делать?

2 ответа

Решение

Ваш print_val обратный вызов должен иметь правильное количество параметров. Если вы посмотрите вверх GtkButton::clicked Сигнал в документации GTK, вы увидите, что он имеет эту подпись:

void user_function (GtkButton *button, gpointer user_data)

Итак, первый параметр передан print_val при нажатии на кнопку находится адрес самой кнопки. Это "странное значение", которое вы печатаете.

Вопреки ответу Дженса здесь, GLib действительно предоставляет портативный способ разыграть int на указатель. Итак, чтобы достичь того, что вы хотите, вам нужно подключить свой сигнал следующим образом:

g_signal_connect(prg->btn, "clicked", G_CALLBACK(print_val), GINT_TO_POINTER(nmb));

а затем сделайте ваш обратный вызов, как это:

static void print_val(GtkButton *button, gpointer nmb)
{
    g_printf("%d\n", GPOINTER_TO_INT(nmb));
}

Я не очень разбираюсь в программировании на gtk, но думаю, это следует прочитать

(gpointer)&nmb

кастинг int в любом случае, указатель не будет хорошей идеей.

Другие вопросы по тегам