GtkTreeViewで選択された項目のデータを取得する
GtkTreeView は MVC (モデル・ビュー・コントロール) に従って構成されていますが、 devhelp のマニュアルを見ても、データの取得方法がよくわかりませんでした。こういう場合は、 zenity の tree.c を見れば良いのですが、 zenity-3.2.0 の tree.c では gtk_tree_selection_selected_foreach () を使って、GList 形式の行のすべてのデータを持ってきているのですが、 devhelp では gtk_tree_selection_get_selected_rows() を使えば良いとなっています。
ということで、今回参考にした URL は、 http://foobar.blog23.fc2.com/blog-entry-164.html です。私が勘違いしていたのは、リスト形式の GtkTreeView で model を GList にした場合、それぞれの行が GList の一項目になっていると思っていたのですが、実際はそれぞれの行が GList になっていて、単一のデータ (例えばテキスト)が一行に書かれている場合は、 GList の最初の項目を持ってこなければならないという事です。
プログラムで書くと、 GtkTreeView *treeview の GtkTreeSelection *selection を取得し、 gtk_tree_selection_get_selected () を利用して、GtkTreeView で利用されている model (GtkTreeModel *model ですが、今回は GList だと分かっている) と、現在選択されている行 (GtkTreeIter iter)を取得し、それから GtkTreeModel を使って、 gtk_tree_model_get () を使って、 iter が示す行から 0 番目の項目だけを取得するって感じになります。
gchar* get_package_name_from_list () { GtkTreeView *treeview; GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gchar *row_string; /* get Widget GtkTreeVew and GtkTreeSelection */ treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview1")); selection = gtk_tree_view_get_selection (treeview); /* get selected iter and iter value as a string */ gtk_tree_selection_get_selected (selection, &model, &iter); gtk_tree_model_get (model, &iter, 0, &row_string, -1); return row_string; }
glade 使っているので、 GtkBuilder *builder はファイル static な変数にしてます。 builder から treeview を取得する説明は割愛して、 selection = gtk_tree_view_get_selection (treeview); でGtkTreeSelection オブジェクトを取得します。 GtkTreeSelection は GtkTreeView に乗っかっていて、この GtkTreeSelection オブジェクトで GtkTreeView の選択情況を知ることができます。
選択されている行を GtkTreeIter として取得し、 GList の最初の項目をコピーした row_string を返しているのが上のプログラムの一部です。
gtk_tree_model_get () は、引数を複数取ることができる関数なので、最後は -1 を入れて終わりにしています。 GTK+ では時々見る番犬ですね。
GtkTreeView は奥が深く、表示は GtkCellRenderer オブジェクトを使って変更したりできるようです。しかし、そこまでするのなら、 glade 使うのではなく、個別にプログラムを書いていったほうが良いような気がします。 devhelp の glade サンプルを以下に引用します。
<object class="GtkTreeView" id="treeview"> <property name="model">liststore1</property> <child> <object class="GtkTreeViewColumn" id="test-column"> <property name="title">Test</property> <child> <object class="GtkCellRendererText" id="test-renderer"/> <attributes> <attribute name="text">1</attribute> </attributes> </child> </object> </child> <child internal-child="selection"> <object class="GtkTreeSelection" id="selection"> <signal name="changed" handler="on_treeview_selection_changed"/> </object> </child> </object>
これを見て、ツリー構造ではなくリスト構造になっていて、リストはテキスト形式になっていることが予想できれば、おそらく問題なく使えると思いますが、これじゃわからないんだよな〜。