GTK3(C语言)生成同组单选按钮列表的问题求助
GTK3 C语言单选按钮组创建问题
在Linux环境下使用GTK3与C语言开发UI时,尝试生成同属一组的单选按钮列表,遇到如下问题:
- 按逻辑创建第一个单选按钮时传入
NULL让GTK自动创建组,后续按钮传入该组指针加入同一组 - 运行后按钮0始终处于选中状态无法取消,其余按钮均可独立切换,未真正归为同一组
原问题代码
生成单选按钮列表的函数
void make_projects_list(GtkWidget *projects_grid) { int n = 20; GSList *group; for (int i =0; i<n; i++) { GtkWidget *radio; char label[3]; snprintf(label, 3, "%d", i); if (i==0) { radio = gtk_radio_button_new_with_label(NULL, label); group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio)); } else { radio = gtk_radio_button_new_with_label(group, label); } gtk_grid_insert_row(GTK_GRID(projects_grid), i); gtk_grid_attach(GTK_GRID(projects_grid), radio, 1, i, 1,1); } }
完整可复现代码
#include<gtk/gtk.h> #include<stdio.h> void make_projects_list(GtkWidget *projects_grid) { int n = 20; GSList *group; for (int i =0; i<n; i++) { GtkWidget *radio; char label[3]; snprintf(label, 3, "%d", i); if (i==0) { radio = gtk_radio_button_new_with_label(NULL, label); group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio)); } else { radio = gtk_radio_button_new_with_label(group, label); } gtk_grid_insert_row(GTK_GRID(projects_grid), i); gtk_grid_attach(GTK_GRID(projects_grid), radio, 1, i, 1,1); } } int main(int argc, char *argv[]) { GtkBuilder *builder; GtkWidget *window; GtkWidget *grid; GError *error = NULL; gtk_init(&argc, &argv); builder = gtk_builder_new(); if (gtk_builder_add_from_file(builder, "build.ui", &error) == 0) { g_printerr("Error loading file: %s\n", error->message); g_clear_error(&error); return 1; } window = GTK_WIDGET (gtk_builder_get_object(builder, "window")); grid = GTK_WIDGET (gtk_builder_get_object(builder, "grid")); gtk_builder_connect_signals(builder, NULL); make_projects_list(grid); gtk_widget_show_all(window); gtk_main(); return 0; }
build.ui 文件内容
<?xml version="1.0" encoding="UTF-8"?> <!-- Generated with glade 3.40.0 --> <interface> <requires lib="gtk+" version="3.24"/> <object class="GtkWindow" id="window"> <property name="can-focus">False</property> <child> <object class="GtkScrolledWindow" id="scrolled_window"> <property name="visible">True</property> <property name="can-focus">True</property> <property name="shadow-type">in</property> <child> <object class="GtkViewport" id="viewport"> <property name="visible">True</property> <property name="can-focus">False</property> <child> <!-- n-columns=1 n-rows=1 --> <object class="GtkGrid" id="grid"> <property name="visible">True</property> <property name="can-focus">False</property> <child> <placeholder/> </child> </object> </child> </object> </child> </object> </child> </object> </interface>
问题原因与解决方案
核心问题
GTK的单选按钮组通过动态GSList维护,每次向组中添加新按钮时,该列表会被更新(新按钮会被加入列表)。原代码仅在创建第一个按钮时获取组指针,后续按钮始终使用初始的组列表(仅包含第一个按钮),导致新按钮实际创建了独立的新组,而非加入目标组。
修复代码
修改make_projects_list函数,在创建每个按钮后更新group指针为最新的组列表,还可简化逻辑无需单独处理第一个按钮:
void make_projects_list(GtkWidget *projects_grid) { int n = 20; GSList *group = NULL; for (int i =0; i<n; i++) { GtkWidget *radio; char label[3]; snprintf(label, 3, "%d", i); radio = gtk_radio_button_new_with_label(group, label); // 更新组指针为最新的组列表 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio)); gtk_grid_insert_row(GTK_GRID(projects_grid), i); gtk_grid_attach(GTK_GRID(projects_grid), radio, 1, i, 1,1); } }
修复说明
- 初始
group设为NULL,第一个按钮创建时GTK会自动生成新组 - 每次创建新按钮后,调用
gtk_radio_button_get_group获取最新的组列表,确保下一个按钮加入的是包含所有已创建按钮的组
内容的提问来源于stack exchange,提问作者thierry oui
相关产品推荐
相关产品推荐

