Gtk3で、ComboBox(DropDown)を作るサンプルコードです。
これまでGtk3では公式ドキュメントを反面教師として、単体動作するコードをサンプルとして提示してきたつもりなのですが、今回は諦めました。すいません。なんというか、実用を目指すプロジェクトからコードを一部だけ、動く状態に抜き出すって無理ですね。
====
// self->combo_linejoin = gtk_combo_box_new();
// GtkListStore *liststore = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
GtkListStore *liststore = gtk_list_store_new(1, G_TYPE_STRING);
int num = get_num_stroke_linejoin_infos();
for(int i = 0; i < num; i++){
const PvStrokeLinejoinInfo *info = get_stroke_linejoin_info_from_id(i);
gtk_list_store_insert_with_values(liststore, NULL, -1,
0, info->name,
// 1, info->linejoin,
-1);
}
self->combo_linejoin = gtk_combo_box_new_with_model(GTK_TREE_MODEL(liststore));
g_object_unref(liststore);
GtkCellRenderer *column = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(self->combo_linejoin), column, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(self->combo_linejoin), column,
"text", 0, NULL);
gtk_combo_box_set_active(GTK_COMBO_BOX(self->combo_linejoin), 0);
gtk_box_pack_start(GTK_BOX(self->box_linejoin), self->combo_linejoin, false, true, 3);
}
====
ついでに使っている独自型などは以下。
====
/*! @brief StrokeLinejoin */
typedef enum{
PvStrokeLinejoin_Miter,
PvStrokeLinejoin_Round,
PvStrokeLinejoin_Bevel,
}PvStrokeLinejoin;
typedef struct{
PvStrokeLinejoin linejoin;
const char *name;
int cairo_value;
}PvStrokeLinejoinInfo;
int get_num_stroke_linejoin_infos();
const PvStrokeLinejoinInfo *get_stroke_linejoin_info_from_id(PvStrokeLinejoin linejoin);
====
ドロップダウンリストの内容をGtkListStoreで作ります。それをGTK_TREE_MODEL形式でcombo_box_new_*()関数に流しこめば完了です。
一番重要なのはGtkListStoreがGtkTreeModelに変換できること、そしてそれがComboBoxに流し込めることです。
Python版コードなどを見てみると、GTK_TREE_MODELのところはタプルとか作ってそのまま流し込んでいて、確かに動的言語なら辞書配列が簡単に作れるし、それがコンボボックスの材料になるのも納得ですが、C言語だとこのなんだかしっくり来ない謎型変換をするコードになっています。
参考にしたのはこちら。
http://stackoverflow.com/questions/16630528/trying-to-populate-a-gtkcombobox-with-model-in-c
参考コードのほうが綺麗で完結していて読みやすいですね。
参考コードはコンボボックスの選択肢に色を付けるという愉快なサンプルコードになっていますが、これもしかしてここからオブジェクト取り出して選択した要素を一意に特定してコールバック処理の際に処理を分岐するとかの用途を想定しているんじゃないかな、私はコールバックの中でアクティブな選択肢の昇順を取ってきて、キャストなどもせず乱暴に元データのIndexに置き換えています。いずれはgpointer *data に選択肢のポインタそのまま投げ込んで判定するつもりだけれど、といった感じです。
====
g_signal_connect(self->combo_linecap, "changed",
G_CALLBACK(_cb_changed_linecap_with_combo), NULL);
static void _cb_changed_linecap_with_combo(GtkComboBox *widget, gpointer user_data)
{
EtStrokePanel *self = stroke_panel;
assert(self);
self->stroke.linecap = gtk_combo_box_get_active(GTK_COMBO_BOX(self->combo_linecap));
_update_focus_elements_from_local();
}
====
以上です。
TIGORA(ティゴラ)のトレッキング シューズ
TIGORA(ティゴラ)の トレッキング シューズを買いました。 メインの靴がアシックスウォーキングで街歩き用なのですが、これまではこれで高尾山などの軽い山も登っていました。 今回、靴底があまりに摩耗したこともあってアシックスウォーキングを買い替えたのですが、ついでに消耗が激...
-
ノートPCの液晶保護フィルムが100円で買えるなんて、良い時代になりました。 ダイソーに行ったら、ノートPCで使えそうな液晶保護フィルムがあったため、衝動的に購入。 A4サイズと書いてあります。私が使っている13インチワイドのノートPCで使えるかどうかわからなかっ...
-
formでユーザの入力やファイルを送信する際、IDを付与したり、送信した情報を紐付けるか、などの情報を一緒に送信したい場合があります。 その場合、ID情報はブラウザに表示しないのがベストです。ユーザに見せたり、編集してもらう必要はありません。 わたしの場合、10個の画像が...
-
Make オルタネイティヴは数あれど、小さな実験プロジェクトを始めるときに、簡単に使えるMakeは未だにビルドツールとして有力な選択肢だと思います。 MakefileはUNIX環境、というかCLIツール群があることを前提にしているところがあります。Windows環境ではUN...