Проблема с g_signal_connect, g_cclosure_new, gpointer - PullRequest
1 голос
/ 23 января 2011
// 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 ]

3 голосов
/ 26 января 2011

Ваш 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));
}
0 голосов
/ 23 января 2011

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

(gpointer)&nmb

приведение int к указателю было бы не очень хорошей идеей.

...