C言語でGTK+ 2を扱う上での幾つかのメモ(第9回)
「C言語でGTK+ 2を扱う上での幾つかのメモ(第8回)」の続きとして、C言語でGTK+ 2のツリービュー(ListStore使用)のテストを行う例を貼り付ける。
[任意]ファイル名: treeviewliststoretest.c
#include <gtk/gtk.h> #include <stdlib.h> /* * C言語によるGTK+のTreeView(ListStore使用)のテスト * * gcc -O2 -Wall -Wextra $(pkg-config --cflags --libs gtk+-2.0) treeviewliststoretest.c -o treeviewliststoretest */ enum { COLUMN_A, /* 最初は0 */ COLUMN_B, COLUMN_C, NUM_COLUMNS, /* 最後のコラム番号の次がコラム数になる */ }; void on_button_clicked (GtkTreeView *tv) /* swapped指定なのでボタンではない */ { GValue *val_a, *val_b, *val_c; GtkTreeIter iter; GtkTreeSelection *selection; GtkTreeModel *model; selection = gtk_tree_view_get_selection (tv); /* * 現在ツリービュー上で選択されている項目(全コラムのまとまり)を取得 * ツリービューに関連付けられているモデル(ここではListStore)の場所を受け取って * 内容にアクセスできるようにする(コピーするのではない) * 関数の中でmodelとiterの内容が書き換えられる */ gtk_tree_selection_get_selected (selection, &model, &iter); /* 取り出す値を入れる領域 */ val_a = g_new0 (GValue, 1); val_b = g_new0 (GValue, 1); val_c = g_new0 (GValue, 1); /* 各コラムの値をListStoreからGValueにコピー */ gtk_tree_model_get_value (model, &iter, COLUMN_A, val_a); gtk_tree_model_get_value (model, &iter, COLUMN_B, val_b); gtk_tree_model_get_value (model, &iter, COLUMN_C, val_c); /* それぞれを元の型として取り出し、端末に表示 */ g_print ("A:%s B:%d C:%s\n", g_value_get_boolean (val_a) ? "TRUE" : "FALSE", g_value_get_int (val_b), g_value_get_string (val_c)); /* g_new0()で確保したデータはg_free()で解放する */ g_free (val_a); g_free (val_b); g_free (val_c); } int main (int argc, char **argv) { GtkListStore *ls; GtkWidget *mainwindow, *menubar, *tv, *sw, *button, *vbox; GtkWidget *item_quit, *item_file, *menu_file; GtkAccelGroup *accelgroup; GtkTreeIter iter; GtkTreeViewColumn *col_a, *col_b, *col_c; gtk_init (&argc, &argv); mainwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); /***** ショートカットキー(アクセラレータ) *****/ accelgroup = gtk_accel_group_new (); gtk_window_add_accel_group (GTK_WINDOW (mainwindow), accelgroup); /***** メニュー項目 *****/ item_quit = gtk_image_menu_item_new_from_stock (GTK_STOCK_QUIT, accelgroup); menu_file = gtk_menu_new (); gtk_menu_shell_append (GTK_MENU_SHELL (menu_file), item_quit); item_file = gtk_menu_item_new_with_mnemonic ("_File"); gtk_menu_item_set_submenu (GTK_MENU_ITEM (item_file), menu_file); menubar = gtk_menu_bar_new (); gtk_menu_bar_append (GTK_MENU_BAR (menubar), item_file); /***** ツリービュー *****/ /*** コラム ***/ /* 最初の2つの引数は表示文字列とセルレンダラオブジェクト */ col_a = gtk_tree_view_column_new_with_attributes ("Column A", gtk_cell_renderer_toggle_new (), /* 「[セルレンダラのGObjectプロパティ名], [コラム番号]」の繰り返し */ "active", COLUMN_A, NULL); /* 最後にNULL */ col_b = gtk_tree_view_column_new_with_attributes ("Column B", gtk_cell_renderer_text_new (), "text", COLUMN_B, NULL); col_c = gtk_tree_view_column_new_with_attributes ("Column C", gtk_cell_renderer_text_new (), "text", COLUMN_C, NULL); /*** データ(ListStore) ***/ ls = gtk_list_store_new (NUM_COLUMNS, G_TYPE_BOOLEAN, /* 真偽値 */ G_TYPE_INT, /* 整数 */ G_TYPE_STRING); /* 文字列 */ /*** ツリービューとその設定 ***/ tv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (ls)); /* モデルと関連付け */ gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col_a); gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col_b); gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col_c); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tv), TRUE); sw = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (sw), tv); /* * ListStoreへのデータの追加 * 今回 * (FALSE, 12345, "test"), (TRUE, 99999, "GTK+"), (FALSE, 838861, "ListStore") * という3つのデータを続けて追加するものとする */ gtk_list_store_append (ls, &iter); gtk_list_store_set (ls, &iter, COLUMN_A, FALSE, /* コラム番号と値のペア(引数2つ単位) */ COLUMN_B, 12345, COLUMN_C, "test", -1); /* -1を最後に付ける */ gtk_list_store_append (ls, &iter); gtk_list_store_set (ls, &iter, COLUMN_A, TRUE, COLUMN_B, 99999, COLUMN_C, "GTK+", -1); gtk_list_store_append (ls, &iter); gtk_list_store_set (ls, &iter, COLUMN_A, FALSE, COLUMN_B, 838861, COLUMN_C, "ListStore", -1); /***** ボタン *****/ button = gtk_button_new_with_mnemonic ("_Get"); /***** 垂直ボックス(縦方向分割) *****/ vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); /***** ウィンドウ *****/ gtk_container_add (GTK_CONTAINER (mainwindow), vbox); gtk_widget_show_all (mainwindow); gtk_widget_set_size_request (mainwindow, 250, 160); gtk_window_resize (GTK_WINDOW (mainwindow), 300, 220); /***** シグナル *****/ g_signal_connect (G_OBJECT (mainwindow), "delete-event", G_CALLBACK (gtk_main_quit), NULL); g_signal_connect (G_OBJECT (item_quit), "activate", G_CALLBACK (gtk_main_quit), NULL); g_signal_connect_object (G_OBJECT (button), "clicked", G_CALLBACK (on_button_clicked), G_OBJECT (tv), G_CONNECT_SWAPPED); /***** メインループ開始 *****/ gtk_main (); return EXIT_SUCCESS; }
実行すると縦方向に3つの項目があり
それぞれを選択した状態でボタンを押すとその内容が
(1つ目の項目を選択してボタンを押す) A:FALSE B:12345 C:test (2つ目の項目を選択してボタンを押す) A:TRUE B:99999 C:GTK+ (3つ目の項目を選択してボタンを押す) A:FALSE B:838861 C:ListStore
のように端末に表示される。
関連記事: