如何在C中使用GTK使用G_CALLBACK获取输入值

时间:2019-01-28 17:07:36

标签: c parameters callback gtk gtk3

我正在使用GTK,CodeBlocks和Glade在学校项目中设置所需的登录窗口。这只是一个简单的表单,用户名,密码和一个连接按钮。问题是我无法获取输入的值,因为无法使用回调将构建器发送到另一个函数。我会尽量简单地解释一下,对不起我的英语不好。

void verifyConnect(GtkButton *button, gpointer *builder){
    GtkWidget *passwordInput;
    GtkWidget *usernameInput;

    passwordInput = GTK_WIDGET(gtk_builder_get_object(*builder, "passwordInput"));
    usernameInput = GTK_WIDGET(gtk_builder_get_object(*builder, "usernameInput"));

    const gchar *text1 = gtk_entry_get_text(GTK_ENTRY(passwordInput));
    const gchar *text2 = gtk_entry_get_text(GTK_ENTRY(usernameInput));

    g_print("Username : %s\n",text2);
    g_print("Password : %s\n",text1);
}


void connectUser(){
    GtkWidget *window;
    GtkWidget *connectButton;

    GtkBuilder *gtkBuilder = gtk_builder_new();
    gtk_builder_add_from_file(gtkBuilder, "loginWindow.glade", NULL);

    window = GTK_WIDGET(gtk_builder_get_object(gtkBuilder, "loginWindow"));

    connectButton = GTK_WIDGET(gtk_builder_get_object(gtkBuilder, "connectButton"));
    g_signal_connect (connectButton, "clicked",G_CALLBACK(verifyConnect),&gtkBuilder);

    g_object_unref(G_OBJECT(gtkBuilder));

    gtk_widget_show(GTK_WIDGET(window));
}

现在,单击连接按钮时出现此错误。 我知道这个错误是什么,我只是不知道如何在verifyConnect函数中获取构建器:

(projet_c_gtk.exe:9928): Gtk-CRITICAL **: gtk_builder_get_object: assertion `GTK_IS_BUILDER (builder)' failed

(projet_c_gtk.exe:9928): Gtk-CRITICAL **: gtk_builder_get_object: assertion `GTK_IS_BUILDER (builder)' failed

(projet_c_gtk.exe:9928): Gtk-CRITICAL **: gtk_entry_get_text: assertion `GTK_IS_ENTRY (entry)' failed

(projet_c_gtk.exe:9928): Gtk-CRITICAL **: gtk_entry_get_text: assertion `GTK_IS_ENTRY (entry)' failed
Username : (null)
Password : (null)

1 个答案:

答案 0 :(得分:0)

罪魁祸首在这里:

g_signal_connect (connectButton, "clicked",G_CALLBACK(verifyConnect),&gtkBuilder);

gtkBuilder变量已经是一个指针,因此将其地址传递给g_signal_connect()最终会使相应的回调参数成为指向指针的指针 。除了一个小细节,这将是一件很不错的事情:您传递的内存地址指向一个自动变量。自动变量存储在堆栈中,并在使用它们的函数返回时释放。之后,其他功能可能会为他们的需求分配相同的空间,并从中重写地狱。

这是您需要解决的问题:

void verifyConnect(GtkButton *button, GtkBuilder *builder){
    GtkWidget *passwordInput;
    GtkWidget *usernameInput;

    passwordInput = GTK_WIDGET(gtk_builder_get_object(builder, "passwordInput"));
    usernameInput = GTK_WIDGET(gtk_builder_get_object(builder, "usernameInput"));

    const gchar *text1 = gtk_entry_get_text(GTK_ENTRY(passwordInput));
    const gchar *text2 = gtk_entry_get_text(GTK_ENTRY(usernameInput));

    g_print("Username : %s\n",text2);
    g_print("Password : %s\n",text1);
}


void connectUser(){
    GtkWidget *window;
    GtkWidget *connectButton;

    GtkBuilder *gtkBuilder = gtk_builder_new();
    gtk_builder_add_from_file(gtkBuilder, "loginWindow.glade", NULL);

    window = GTK_WIDGET(gtk_builder_get_object(gtkBuilder, "loginWindow"));

    connectButton = GTK_WIDGET(gtk_builder_get_object(gtkBuilder, "connectButton"));
    g_signal_connect(connectButton, "clicked", G_CALLBACK(verifyConnect), gtkBuilder);

    g_object_unref(G_OBJECT(gtkBuilder));

    gtk_widget_show(GTK_WIDGET(window));
}

当参数通过值传递时,它不再依赖于存储在其先前位置中的任何内容。

…aaa和BTW,您确定要在gtkBuilder内释放connectUser()吗?您也正在verifyConnect()中使用它,因此可能必须在verifyConnect()的末尾释放它,而不是在connectUser()的末尾释放它。