关于g_signal_connect、g_cclosure_new、gpointer的问题

发布于 2024-10-13 04:37:47 字数 1805 浏览 3 评论 0原文

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

我想让这个程序在每次按下按钮或 Ctrl + Shift + P 时在控制台上打印 140。

但是当我按下按钮或 Ctrl + Shirt + P 时,这个程序会打印奇怪的值(不是 140)。

我应该做什么做?

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

I want to make this program to print 140 on console every time I pressed the button or Ctrl + Shift + P.

But this program prints the weird value(not 140) when I pressed the button or Ctrl + Shirt + P.

What should I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北笙凉宸 2024-10-20 04:37:47

您的 print_val 回调需要具有正确数量的参数。如果您在 GTK 文档中查找 GtkButton::clicked 信号,您将看到它具有以下签名:

void user_function (GtkButton *button, gpointer user_data)

因此,当您单击按钮时传递给 print_val 的第一个参数是按钮本身的地址。这是您正在打印的“奇怪的值”。

与 Jens 的回答相反,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));
}

Your print_val callback needs to have the correct number of parameters. If you look up the GtkButton::clicked signal in the GTK documentation, you will see it has this signature:

void user_function (GtkButton *button, gpointer user_data)

So the first parameter passed to print_val when you click the button is the address of the button itself. This is the "weird value" you are printing.

Contrary to Jens' answer here, GLib does provide a portable way to cast an int to a pointer. So to achieve what you want, you need to connect your signal like this:

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

and then make your callback like this:

static void print_val(GtkButton *button, gpointer nmb)
{
    g_printf("%d\n", GPOINTER_TO_INT(nmb));
}
鸠书 2024-10-20 04:37:47

我对 gtk 编程了解不多,但我想这应该是把

(gpointer)&nmb

int 转换为指针,无论如何,这不是一个好主意。

I don't know much about gtk programming but I guess this should read

(gpointer)&nmb

casting an int to a pointer would not be a good idea, anyhow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文