C语言GTK+如何在按钮点击事件中传递多个控件到回调函数
错误原因分析
- 第一版代码错误:
传入回调的entries是存储GtkWidget*类型的二维数组,你在回调中直接强制转换为double**类型,类型完全不匹配,自然无法读取到控件的文本内容。 - 第二版更新后的代码错误:
- C语言中
GtkWidget *entries[10][10]这类固定长度二维数组的内存是连续排布的,100个GtkWidget*指针依次存储,不存在单独的行指针数组。你使用的*(values+i) + j偏移逻辑是为指针数组设计的,无法匹配连续存储的二维数组的地址计算规则,导致除第一个元素外的地址全部偏移错误。 - 回调函数的第二个参数固定为
gpointer类型,你写成gpointer *data属于参数类型定义错误,虽然运行时可能不会直接崩溃,但属于不符合规范的写法。
- C语言中
正确实现方式
方案1:直接传递二维数组(推荐,写法最直观)
信号绑定保持最初的写法即可:
g_signal_connect(btn, "clicked", G_CALLBACK(calculate), entries);
回调函数按二维数组的正确类型转换:
void calculate(GtkWidget *btn, gpointer data){ // 将data转换为指向「长度为10的GtkWidget*数组」的指针,匹配entries的类型 GtkWidget *(*values)[10] = data; for(int i = 0; i < 10; i++){ for(int j = 0; j < 10; j++){ const gchar *text = gtk_entry_get_text(GTK_ENTRY(values[i][j])); printf("%s ", text); // 后续需要转数值可以用g_ascii_strtod(text, NULL)转换 } printf("\n"); } }
方案2:传递首元素指针的修正写法
如果你坚持使用传递首元素指针的方式,需要调整地址偏移逻辑:
信号绑定:
g_signal_connect(btn, "clicked", G_CALLBACK(calculate), &entries[0][0]);
回调函数修正偏移计算:
void calculate(GtkWidget *btn, gpointer data){ GtkWidget **values = (GtkWidget **) data; for(int i = 0; i < 10; i++){ for(int j = 0; j < 10; j++){ // 每行占10个元素,总偏移为i*10 +j const gchar *text = gtk_entry_get_text(GTK_ENTRY(values[i * 10 + j])); printf("%s\n", text); } } }
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

