試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

C言語のGTK+でListStoreからデータを取り出す処理に関する追加メモ(前半)

C言語でGTK+ 2を扱う上での幾つかのメモ(第8回)」ではListStoreというデータ構造(オブジェクト)からデータを取り出すときにgtk_tree_model_get_value()とGValue型のデータを用いたが、これは値を取り出す際に型を柔軟に扱える反面、処理に面倒なところがある。しかし、この代わりにgtk_tree_model_get()という関数を用いると、元々のデータに合った型を用意しておき、「コラム番号」と「書き込み先の変数の場所(&[変数名])」のペアを指定することで、取り出したデータを直接入れることができる。ペアを指定する部分は可変長なので同時に複数のコラムのデータを取得することもできる。
Vala言語でも同様の要領(ListStoreオブジェクトのメンバ関数get())でできるが、書き込み先は「out」指定*1になる。また、C言語では最後に「-1」を指定する必要があるがVala言語では不要。
C言語に話を戻すが、文字列を取り出す場合は新しくメモリ領域が確保されるためそれを後でg_free()で解放する。C言語でGTK+ 2を扱う上での幾つかのメモ(第9回)」の例の該当部分は

void
on_button_clicked (GtkTreeView *tv)
{
  /* 今回は真偽値/整数/文字列としたので、それぞれの変数を用意しておく */
  gboolean ret_a;
  gint ret_b;
  gchar *ret_c;

  GtkTreeIter iter;
  GtkTreeSelection *selection;
  GtkTreeModel *model;  /* GtkListStoreクラスが実装しているインターフェース */

  selection = gtk_tree_view_get_selection (tv);
  gtk_tree_selection_get_selected (selection, &model, &iter);
  gtk_tree_model_get (model, &iter,
                      /* コラム番号と書き込み先のペア(可変長) */
                      COLUMN_A, &ret_a,
                      COLUMN_B, &ret_b,
                      COLUMN_C, &ret_c,
                      /* 最後に-1を付ける */
                      -1);
  ...

  /* 文字列はg_free()で解放する */
  g_free (ret_c);
}

のようになる。
ListStoreの項目にGObjectオブジェクト(gtk_list_store_new()で型を指定する引数はG_TYPE_OBJECT)が入っている場合はGObject *型の変数を宣言してgtk_tree_model_get()で書き込み、必要なくなったらg_object_unref()で参照カウンタを減らす。下は「C言語でGTK+ 2を扱う上での幾つかのメモ(第9回)」の例を変えてGdkPixbuf(画像データのオブジェクト)を入れてそれを取り出す例の一部。

GtkTreeViewColumn *col_a, *col_b;
GtkListStore *ls;
col_a = gtk_tree_view_column_new_with_attributes ("Column A",
                                                  gtk_cell_renderer_text_new (),
                                                  "text", COLUMN_A,
                                                  NULL);
col_b = gtk_tree_view_column_new_with_attributes ("Column B",
                                                  /* GdkPixbufを表示するセルレンダラ */
                                                  gtk_cell_renderer_pixbuf_new (),
                                                  "pixbuf", COLUMN_B,
                                                  NULL);
ls = gtk_list_store_new (NUM_COLUMNS,
                         G_TYPE_INT,
                         G_TYPE_OBJECT);


...


gint ret_a;
GObject *ret_b;  /* ここではGObjectクラスのオブジェクトとして扱う */
GtkTreeIter iter;
GtkTreeModel *model;

...

gtk_tree_model_get (model, &iter,
                    COLUMN_A, &ret_a,
                    COLUMN_B, &ret_b,
                    -1);

...

/* GdkPixbuf *型の引数を渡す場面ではマクロで型変換する(下は実在しない関数名なので注意) */
val = gdk_pixbuf_foo (GDK_PIXBUF (ret_b));

...

/* オブジェクトはg_object_unref()で参照カウンタを減らす */
g_object_unref (ret_b);

コードの全体は後半に貼り付ける。

(「C言語のGTK+でListStoreからデータを取り出す処理に関する追加メモ(後半)」に続く)

関連記事:

参考URL:

*1:宣言した変数に値を入れるのが目的なので「ref」ではない