GTK4使用GtkColumnView最佳实践
gtk4丢弃很多gtk3的类,GtkColumnView是新版本的其中之一,今天就用GtkColumnView实现常用的操作。
以下示例代码实现了动态增加列表数据,一行用多个控件,双击响应事件,以及单选和多选处理逻辑
#define ELEM_NUM 2 #define G_UTF8(s) g_locale_to_utf8(s, -1, 0, 0, 0) static void columnview_setup_listitem_cb(GtkListItemFactory* factory, GtkListItem* list_item, gpointer user_data) { int col = (int)user_data; printf("columnview_setup_listitem_cb %d\n", col); GtkWidget* box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10); for (int i = 0; i < ELEM_NUM; i++) { GtkWidget* label = gtk_label_new(""); gtk_box_append(GTK_BOX(box), label); } gtk_list_item_set_child(list_item, box); } static void columnview_bind_listitem_cb(GtkListItemFactory* factory, GtkListItem* list_item, gpointer user_data) { int col = (int)user_data; printf("columnview_bind_listitem_cb %d\n", col); GtkWidget* box = gtk_list_item_get_child(list_item); GListModel* listmodel = G_LIST_MODEL(gtk_list_item_get_item(list_item)); GtkStringList* stringlist = GTK_STRING_LIST(g_list_model_get_item(listmodel, col)); GtkWidget* label = gtk_widget_get_first_child(box); for (int i = 0; i < ELEM_NUM; i++) { gtk_label_set_label(GTK_LABEL(label), gtk_string_list_get_string(stringlist, i)); label = gtk_widget_get_next_sibling(label); } } static void on_columnview_list_item_double_click(GtkGestureClick* gesture, gint n_press, gdouble x, gdouble y, gpointer user_data) { if (n_press == 2) { GtkColumnView* columnview = GTK_COLUMN_VIEW(user_data); //单选/多选通用方法 GtkSelectionModel* selectionmodel = gtk_column_view_get_model(columnview); GtkBitset* selected_items = gtk_selection_model_get_selection(selectionmodel); if (selected_items) { guint value = 0; GtkBitsetIter iter = {}; for (gboolean b = gtk_bitset_iter_init_first(&iter, selected_items, &value); b == TRUE; b = gtk_bitset_iter_next(&iter, &value)) { value = gtk_bitset_iter_get_value(&iter); g_print("Selected item: %u\n", value); GListStore* _liststore = G_LIST_STORE(g_list_model_get_object(G_LIST_MODEL(selectionmodel), value)); for (int i = 0; i < ELEM_NUM; i++) { GtkStringList* stringlist = GTK_STRING_LIST(g_list_model_get_item(G_LIST_MODEL(_liststore), i)); for (int j = 0; j < ELEM_NUM; j++) { g_print("%s\n", gtk_string_list_get_string(stringlist, j)); } } } } //若单选可如此 GListStore* _liststore = G_LIST_STORE(gtk_single_selection_get_selected_item(GTK_SINGLE_SELECTION(selectionmodel))); g_print("Double-clicked on item: \n"); for (int i = 0; i < ELEM_NUM; i++) { GtkStringList* stringlist = GTK_STRING_LIST(g_list_model_get_item(G_LIST_MODEL(_liststore), i)); for (int j = 0; j < ELEM_NUM; j++) { g_print("%s\n", gtk_string_list_get_string(stringlist, j)); } } { GListStore* liststore = G_LIST_STORE(gtk_single_selection_get_model(GTK_SINGLE_SELECTION(selectionmodel))); int n_old = g_list_model_get_n_items(G_LIST_MODEL(liststore)); const char* listdata[][ELEM_NUM + 1][ELEM_NUM + 1] = { {{G_UTF8("ccc"),G_UTF8("ddd"),}, {G_UTF8("ddd"),G_UTF8("eee"),}, {G_UTF8("ddd"),G_UTF8("eee"),}, }, {{G_UTF8("ccc1"),G_UTF8("ddd1"),}, {G_UTF8("ddd1"),G_UTF8("eee1"),}, {G_UTF8("ddd1"),G_UTF8("eee1"),}, }, }; int n = sizeof(listdata) / sizeof(*listdata); printf("n_old=%d,%d\n", n_old, n); for (int i = 0; i < n; i++) { GListStore* _liststore = g_list_store_new(G_TYPE_OBJECT); for (int j = 0; j < ELEM_NUM + 1; j++) { printf("%d,%s,%s\n", i, listdata[i][j][0], listdata[i][j][1]); GtkStringList* stringlist = gtk_string_list_new(listdata[i][j]); //GtkStringList* stringlist = gtk_string_list_new(NULL); //for (int k = 0; k < ELEM_NUM; k++) //{ // gtk_string_list_append(_liststore, listdata[i][j][k]); //} g_list_store_append(_liststore, stringlist); } g_list_store_append(liststore, _liststore); } g_list_model_items_changed(G_LIST_MODEL(liststore), n_old - 1, 0, 0); } } } void columnview_test(GtkApplication* app) { GtkWidget* win = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(win), G_UTF8("GTK4列表例子")); gtk_window_set_default_size(GTK_WINDOW(win), 800, 600); GtkWidget* scrolledwindow = gtk_scrolled_window_new(); gtk_window_set_child(GTK_WINDOW(win), scrolledwindow); GListStore* liststore = g_list_store_new(G_TYPE_OBJECT); const char* listdata[][ELEM_NUM + 1][ELEM_NUM + 1] = { {{G_UTF8("aaa"),G_UTF8("bbb"),}, {G_UTF8("bbb"),G_UTF8("ccc"),},{G_UTF8("bbb"),G_UTF8("ccc"),},}, {{G_UTF8("eee"),G_UTF8("fff"),}, {G_UTF8("vvv"),G_UTF8("bbb"),},{G_UTF8("vvv"),G_UTF8("bbb"),},}, }; int n = sizeof(listdata) / sizeof(*listdata); printf("n=%d\n", n); for (int i = 0; i < n; i++) { GListStore* _liststore = g_list_store_new(G_TYPE_OBJECT); for (int j = 0; j < ELEM_NUM + 1; j++) { printf("%d,%s,%s\n", i, listdata[i][j][0], listdata[i][j][1]); GtkStringList* stringlist = gtk_string_list_new(listdata[i][j]); //GtkStringList* stringlist = gtk_string_list_new(NULL); //for (int k = 0; k < ELEM_NUM; k++) //{ // gtk_string_list_append(_liststore, listdata[i][j][k]); //} g_list_store_append(_liststore, stringlist); } g_list_store_append(liststore, _liststore); } //GtkTreeSelection; GtkSelectionModel* selectionmodel = GTK_SELECTION_MODEL(gtk_single_selection_new(G_LIST_MODEL(liststore))); GtkWidget* columnview = gtk_column_view_new(selectionmodel); gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrolledwindow), columnview); const char* column_names[] = { G_UTF8("姓名"),G_UTF8("性别"),G_UTF8("年龄"), }; for (int i = 0; i < sizeof(column_names) / sizeof(*column_names); i++) { GtkListItemFactory* factory = gtk_signal_list_item_factory_new(); g_signal_connect(factory, "setup", G_CALLBACK(columnview_setup_listitem_cb), (gpointer)i); g_signal_connect(factory, "bind", G_CALLBACK(columnview_bind_listitem_cb), (gpointer)i); GtkColumnViewColumn* columnviewcolumn = gtk_column_view_column_new(column_names[i], factory); gtk_column_view_column_set_expand(columnviewcolumn, TRUE); gtk_column_view_column_set_resizable(columnviewcolumn, TRUE); gtk_column_view_append_column(GTK_COLUMN_VIEW(columnview), columnviewcolumn); } gtk_column_view_set_show_column_separators(GTK_COLUMN_VIEW(columnview), TRUE); gtk_column_view_set_show_row_separators(GTK_COLUMN_VIEW(columnview), TRUE); GtkGesture* gesture = gtk_gesture_click_new(); gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture), GDK_BUTTON_PRIMARY); gtk_widget_add_controller(columnview, GTK_EVENT_CONTROLLER(gesture)); g_signal_connect(gesture, "pressed", G_CALLBACK(on_columnview_list_item_double_click), columnview); gtk_window_present(GTK_WINDOW(win)); { int n_old = g_list_model_get_n_items(G_LIST_MODEL(liststore)); printf("n_old=%d,%d\n", n_old, n); for (int i = 0; i < n; i++) { GListStore* _liststore = g_list_store_new(G_TYPE_OBJECT); for (int j = 0; j < ELEM_NUM + 1; j++) { printf("%d,%s,%s\n", i, listdata[i][j][0], listdata[i][j][1]); GtkStringList* stringlist = gtk_string_list_new(listdata[i][j]); //GtkStringList* stringlist = gtk_string_list_new(NULL); //for (int k = 0; k < ELEM_NUM; k++) //{ // gtk_string_list_append(_liststore, listdata[i][j][k]); //} g_list_store_append(_liststore, stringlist); } g_list_store_append(liststore, _liststore); } g_list_model_items_changed(G_LIST_MODEL(liststore), n_old - 1, 0, 0); } } static void activate(GtkApplication* app, gpointer user_data) { columnview_test(app); return; }
收藏的用户(0)
X
正在加载信息~
2
最新回复 (0)