c - 如何在 C 中使用 GTK 使用 G_CALLBACK 获取输入值
问题描述
我正在使用 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),>kBuilder);
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)
解决方案
罪魁祸首在这里:
g_signal_connect (connectButton, "clicked",G_CALLBACK(verifyConnect),>kBuilder);
该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));
}
当参数按值传递时,它不再依赖于存储在其先前位置的任何内容。
…aaaand BTW,你真的确定你需要在gtkBuilder
里面自由connectUser()
吗?您也在使用它verifyConnect()
,所以您可能必须在 . 结尾处释放它verifyConnect()
,而不是在connectUser()
.
推荐阅读
- java - 运行测试时获取“java.lang.IllegalArgumentException:解码参数不能为空”
- elasticsearch - 如何在弹性搜索查询中组合和
- r - 无法在 R 中链接 CPLEX 库
- java - 如何使用 SharedPreferences 存储布尔值?
- file - 尝试获取一些脚本以根据文件名的前 4 个字符将 pdf 文件移动到文件夹中
- java - Spring-batch 没有得到属性 spring.batch.table-prefix
- excel - 我陷入了无限循环
- javascript - 如何从前端(ejs/html)调用restapi函数
- c# - WinAppDriver - FindElementsByName / FindElementsByAccessibilityId 花费的时间越来越多,并且随时间线性增加
- php - Eloquent - 如何在没有观察者的情况下等到 create() 之后