C言語でGTK+ 2を扱う上での幾つかのメモ(第8回)
「C言語でGTK+ 2を扱う上での幾つかのメモ(第7回)」の続き。
ListStoreに対するデータの出し入れとツリービュー関係の操作
ツリービューなどで表示するデータとして用いるListStoreというデータ構造に対するデータの出し入れの形がC言語やVala言語ではPyGTKとは異なる。
ListStoreはイメージとしては構造体をデータ(中身)とするリスト構造に近く、各データには複数の値を持たせることができ(型は順番ごとに固定)、リストのようにデータの追加や削除などが行える。このデータはツリービューやコンボボックスといったGUI部品と関連付けてその内容を表示するようにできる。内部的にはGUI部品などと同様のGObjectオブジェクト。
ListStoreオブジェクトの作成
ListStoreオブジェクトを作成するにはgtk_list_store_new()を呼び、最初の引数にコラム数,その後ろにはコラムの数だけ型を指定するマクロ(G_TYPE_[型名])を指定する。型はgint64のようなbit数を保証しているもの(例:G_TYPE_INT64)を用いることもできる。
enum { COLUMN_A, COLUMN_B, COLUMN_C, NUM_COLUMNS, }; ... /* この場合、それぞれのデータが(真偽値, 整数, 文字列)の3つの値をまとめて持つことになる */ GtkListStore *ls = gtk_list_store_new (NUM_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_STRING);
ツリービューコラムとセルレンダラ
ツリービューのコラムのオブジェクトの作成にはgtk_tree_view_column_new_with_attributes()を用い、引数が「コラム名,セルレンダラオブジェクト,(セルレンダラのGObjectプロパティ名と対応するコラム番号の繰り返し),NULL」となっているものの、要領はPyGTKと同様で、ツリービューへの追加の要領も同様。
GtkTreeViewColumn *col_a, *col_b, *col_c; GtkListStore *ls; GtkWidget *tv; /* 最初の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 = [略] ; ls = gtk_list_store_new ( [略] ); 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);
ListStoreにデータを入れる
PyGTKでは言語バインディングの親切機能によりPythonのタプルという形でデータを追加することができたが、C言語では
- 追加後のデータを入れる場所を指し示すためのGtkTreeIter型構造体を用意(宣言する)
- 追加用の関数(gtk_list_store_append()など)を呼ぶとGtkTreeIter型構造体に場所が設定される
- 受け取った場所を指定してデータ書き込み用の関数(gtk_list_store_set()など)を呼び、そこへデータを書き込む
といった流れで作業を行う。Vala言語でも内部的にはC言語のGTK+のコードを生成することになり、要領もこれに同じとなる。
データを取り出す
C言語におけるListStoreからのデータの取り出しは多少面倒。
まずは取り出したい項目を指し示すGtkTreeIter型構造体を宣言しておき、「gtk_tree_model_get_iter*」系関数や、それにより得たものを「gtk_tree_model_iter*」系関数で動かしたものを用意し、これとListStoreにおける取り出したいコラム番号をGtkTreeModelインターフェースのgtk_tree_model_get_value()などに渡すことで中の個別のコラムのデータが取り出せる。
しかし、この関数への引数として渡すのはGValueという型へのポインタとなっており、下のような形でデータを確保する。
GValue *val = g_new0 (GValue, 1);
この後gtk_tree_model_get_value()などを呼び、中にデータが入った後は、GObjectライブラリ内のg_value_get_[型名]()の関数でそれぞれの型としてのデータを得ることになる。例えば、取り出したいデータのコラムが(g)int型の場合は
gint val_int = g_value_get_int (val);
のようにして取り出す(ListStore上で決めた型と一致する必要がある)。型はGLibが用意する様々な型に対応しており、もちろん(g)int64などの「環境によらずbit数を保証する」類の型も利用できる。
なお、データは動的に確保されたものなので、後で手動で解放する必要がある。
g_free (val);
Vala言語ではGLib.Value型構造体を用いるが、この構造体のget_int()などのメンバ関数を用いて型を指定して取り出すことになる。データの解放は構造体変数の寿命とともに自動的に行われる。
(「C言語でGTK+ 2を扱う上での幾つかのメモ(第9回)」に続く)
関連記事:
- PyGTKでツリービューにリストのデータ(ListStore)を表示(概要とメモ)
- C言語でGTK+ 2を扱う上での幾つかのメモ(第1回)
- C言語でGTK+ 2を扱う上での幾つかのメモ(第2回)
- C言語でGTK+ 2を扱う上での幾つかのメモ(第3回)
- C言語でGTK+ 2を扱う上での幾つかのメモ(第4回)
- C言語でGTK+ 2を扱う上での幾つかのメモ(第5回)
- C言語でGTK+ 2を扱う上での幾つかのメモ(第6回)
- C言語でGTK+ 2を扱う上での幾つかのメモ(第7回)
- GLib 2が用意している基本的なデータ型について(ページ2/3)
- C言語でGTK+ 2を扱う上での幾つかのメモ(第9回)
参考URL: