Show page source of Gtk/GtkTreeView #40421

= GtkTreeView

Gtk+-1.2にあったGtkCListやGtkTree、GtkCTreeに代わるもの。GtkTreeViewでは、見た目やデータを分離したModel/View/Controllerという設計が取られている。

= 関連するWidgetやデータ型

== GtkTreeView

 ツリー型のViewを実現するWidget。後述のGtkTreeViewColumnのコンテナとなっている。なお、GtkTreeModelなどと接続されるまで実際の描画は行われない模様。(Modelの中身は空でも良い。)

=== 生成するための関数プロトタイプ

{{{ code c
GtkWidget* gtk_tree_view_new(void);
}}}

他のWidgetと同じでGtkWidget型へのポインタを返すことに注意。

== GtkTreeViewColumn

GtkTreeViewに列を表現するためのWidget。後述のGtkCellRendererのコンテナとなっている。

=== 生成するための関数プロトタイプ

{{{ code c
GtkTreeViewColumn* gtk_tree_view_column_new (void);
}}}

こいつはまんまGtkTreeViewColumn型へのポインタを返す。

=== GtkTreeViewとの関連付け関数

{{{ code c
gint        gtk_tree_view_append_column     (GtkTreeView *tree_view,
					     GtkTreeViewColumn *column);
gint        gtk_tree_view_insert_column     (GtkTreeView *tree_view,
                                             GtkTreeViewColumn *column,
                                             gint position);
}}}

などがある。ともに何番目の列となったかが戻り値となる。

== GtkCellRenderer

セルを表現するためのWidget。文字列や画像、真偽のいずれを扱うかによってGtkCellRendererText、GtkCellRendererPixbuf、GtkCellRendererToggleに分類される。真偽は、トグルボタンとして表現される。その特性上、一つのGtkTreeColumnに対して複数のGtkCellRendererをパッキングすることが可能。

=== 生成するための関数プロトタイプ

{{{ code c
GtkCellRenderer* gtk_cell_renderer_text_new (void);
GtkCellRenderer* gtk_cell_renderer_pixbuf_new(void);
GtkCellRenderer* gtk_cell_renderer_toggle_new(void);
}}}

順にGtkCellRendererText、GtkCellRendererPixbuf、GtkCellRendererToggleを生成するが、全てGtkCellRenderer型へのポインタを返す。

= GtkCellRenderで設定可能なプロパティ

gtk_tree_view_column_add_attributeなどで設定できるプロパティの種類

== GtkCellRendererText

||"attributes"||PangoAttrList||Read / Write|| ||
||"background"||gchararray||Write|| ||
||"background-gdk"||GdkColor||Read / Write|| ||
||"background-set"||gboolean||Read / Write|| ||
||"editable"||gboolean||Read / Write|| ||
||"editable-set"||gboolean||Read / Write|| ||
||"family"||gchararray||Read / Write|| ||
||"family-set"||gboolean||Read / Write|| ||
||"font"||gchararray||Read / Write|| ||
||"font-desc"||PangoFontDescription||Read / Write|| ||
||"foreground"||gchararray||Write|| ||
||"foreground-gdk"||GdkColor||Read / Write|| ||
||"foreground-set"||gboolean||Read / Write|| ||
||"language"||gchararray||Read / Write|| ||
||"language-set"||gboolean||Read / Write|| ||
||"markup"||gchararray||Write|| ||
||"rise"||gint||Read / Write|| ||
||"rise-set"||gboolean||Read / Write|| ||
||"scale"||gdouble||Read / Write|| ||
||"scale-set"||gboolean||Read / Write|| ||
||"single-paragraph-mode"||gboolean||Read / Write|| ||
||"size"||gint||Read / Write|| ||
||"size-points"||gdouble||Read / Write|| ||
||"size-set"||gboolean||Read / Write|| ||
||"stretch"||PangoStretch||Read / Write|| ||
||"stretch-set"||gboolean||Read / Write|| ||
||"strikethrough"||gboolean||Read / Write||打ち消し線||
||"strikethrough-set"||gboolean||Read / Write|| ||
||"style"||PangoStyle||Read / Write|| ||
||"style-set"||gboolean||Read / Write|| ||
||"text"||gchararray||Read / Write|| ||
||"underline"||PangoUnderline||Read / Write|| ||
||"underline-set"||gboolean||Read / Write|| ||
||"variant"||PangoVariant||Read / Write|| ||
||"variant-set"||gboolean||Read / Write|| ||
||"weight"||gint||Read / Write|| ||
||"weight-set"||gboolean||Read / Write|| ||

== GtkCellRendererPixbuf

||"pixbuf"||GdkPixbuf||Read / Write||
||"pixbuf-expander-closed"||GdkPixbuf||Read / Write||
||"pixbuf-expander-open"||GdkPixbuf||Read / Write||
||"stock-detail"||gchararray||Read / Write||
||"stock-id"||gchararray||Read / Write||
||"stock-size"||guint||Read / Write||

== GtkCellRendererToggle

||"activatable"||gboolean||Read / Write||
||"active"||gboolean||Read / Write||
||"inconsistent"||gboolean||Read / Write||
||"radio"||gboolean||Read / Write||

= GtkTreeModel

= GtkTreeStore,GtkListStore

== 列(フィールド)に設定できる型

 * G_TYPE_BOOLEAN
 * G_TYPE_INT, G_TYPE_UINT
 * G_TYPE_LONG, G_TYPE_ULONG, G_TYPE_INT64, G_TYPE_UINT64 (these are not supported in early gtk+-2.0.x versions)
 * G_TYPE_FLOAT, G_TYPE_DOUBLE
 * G_TYPE_STRING - stores a string in the store (オリジナルの文字列のコピーを作成する。)
 * G_TYPE_POINTER - stores a pointer value (Storeの中には、全くコピーを作成せず、ただポインタのみが保存される。)
 * GDK_TYPE_PIXBUF - stores a GdkPixbuf in the store (increases the pixbuf's refcount, see below)

G_TYPE_POINTERを除いてメモリの解放を心配する必要はない。GtkTreeViewが破棄されると同時に解放される。つまり、G_TYPE_POINTER型のフィールドについては、プログラマでメモリの解放の面倒を見る必要がある。


= 関連リンク

 * [http://developer.gnome.org/doc/API/2.0/gtk/TreeWidgetObjects.html Tree and List Widget]
 * [http://scentric.net/tutorial/treeview-tutorial.html GTK+ 2.0 Tree View Tutorial]

= その他のメモ

== カーソル位置

 * gtk_tree_view_set_cursor ()
 * gtk_tree_view_set_cursor_on_cell ()
 * gtk_tree_view_get_cursor ()

== ノードの展開と省略

 * gtk_tree_view_expand_all ()
 * gtk_tree_view_collapse_all ()
 * gtk_tree_view_expand_to_path ()
 * gtk_tree_view_expand_row ()
 * gtk_tree_view_collapse_row ()

== 検索

 * gtk_tree_view_set_enable_search ()
 * gtk_tree_view_get_enable_search ()
 * gtk_tree_view_get_search_column ()
 * gtk_tree_view_set_search_column ()
 * gtk_tree_view_get_search_equal_func ()
 * gtk_tree_view_set_search_equal_func ()

== gtk_tree_model_getでG_TYPE_STRING型の項目を取得する場合

{{{ code c
 gchar *path; // 初期化の必要無し
 
 (中略)
 
 gtk_tree_model_get (GTK_TREE_MODEL (store), iter, COL_FULL_PATH, &path, -1);
}}}

受け取るgchar型のポインタについては、初期化の必要はないが、&を用いてポインタへのポインタを渡すこと。

== 実際に表示する項目については、UTF-8化して置くこと

でないとPangoがレンダリングできない。

 * g_convert
 * g_locale_to_utf8

などを利用。非表示の項目についてはそのままでも可。

== ダミーノードを使って展開されたときに新たにchildを作る

ダミーノードを削除するのは、必要なchildを作成してから。でないと削除した時点で展開が解かれてしまう。

== gtk_list_store_setでは、コピーが格納される。(G_TYPE_POINTERを除く)

http://scentric.net/tutorial/sec-treemodel-data-manipulation.html

> You do not need to worry about allocating and freeing memory for the data to store. The model (or more precisely: the GLib/GObject GType and GValue system) will take care of that for you. If you store a string, for example, the model will make a copy of the string and store that. If you then set the field to a new string later on, the model will automatically free the old string and again make a copy of the new string and store the copy. This applies to almost all types, be it G_TYPE_STRING or GDK_TYPE_PIXBUF.

== gtk_tree_model_getで取得したデータは、解放する必要がある

http://scentric.net/tutorial/sec-treemodel-data-retrieval.html より

{{{ code c
     gchar *first_name, *last_name, *tree_path_str;
     guint  year_of_birth;
 
     /* Note: here we use 'iter' and not '&iter', because we did not allocate
      *  the iter on the stack and are already getting the pointer to a tree iter */
 
     gtk_tree_model_get (model, iter,
                         COL_FIRST_NAME, &first_name,
                         COL_LAST_NAME, &last_name,
                         COL_YEAR_BORN, &year_of_birth,
                         -1);
 
     tree_path_str = gtk_tree_path_to_string(path);
 
     g_print ("Row %s: %s %s, born %u\n", tree_path_str,
              first_name, last_name, year_of_birth);
 
     g_free(tree_path_str);
 
     g_free(first_name); /* gtk_tree_model_get made copies of       */
     g_free(last_name);  /* the strings for us when retrieving them */
}}}

== GdkCellRendererPixbufでストックアイコンを表示したい場合

Gtk+で標準で用意されているストックアイコンを使用するには、GdkCellRendererPixbufの"stock-id"プロパティを設定する。その場合、関係する列は、G_TYPE_STRINGである必要があり、ストックアイコンのストックIDを格納する。

ストックIDについては、以下を参照。

http://developer.gnome.org/doc/API/2.0/gtk/gtk-Stock-Items.html

== GtkTreeStoreと違ってGtkListStoreは、二度と取得できない?

GtkTreeModelを取得して、GTK_LIST_STOREでキャストすると大丈夫。

== GDK_TYPE_PIXBUFのフィールドがある時

gtk_tree_store_set()において画像がない場合には、明示的にNULLをセットすること。でないとセグフォが起こる。