GTK+ †
GTK+ プログラミングに関する tips など。
GtkTreeViewで各行ごとの高さが一定である場合は、
g_object_set(treeview, "fixed-height-mode", TRUE, NULL);
のようにして fixed-height-mode を有効にすると描画が高速化される。
(また、GTK+ 2.6以降では gtk_tree_view_set_fixed_height_mode() 関数が追加されている)
GtkTreeStoreに大量の行(数千〜)を追加する場合は、
gtk_tree_store_append()よりgtk_tree_store_prepend()を使用するほうが
圧倒的に高速である。
appendする場合は内部のリストを先頭から順に辿っていき、
追加する場所を探すという動作を行っているために
O(n^2)のオーダーで処理量が増加していくためである。
また、GtkTreeStoreをクリアしたり大量の行を追加したりする場合は、
gtk_tree_view_set_model(tree_view, NULL);
として一度modelをviewから切り離し、処理が完了してから再びviewに
modelを設定するほうが1.5倍程度高速になる。
GtkTreeModel? †
gtk_tree_model_get_flags()でGTK_TREE_MODEL_ITERS_PERSISTフラグが立っているGtkTreeModel?(GtkListStore?、GtkTreeStoreが該当)では、modelに変更があった後でもGtkTreeIter?は有効なままである。
(GtkTextBuffer?とは異なる)
GtkTreeViewはデフォルトの状態では行間のマージンがかなり大きくとられているが、
これを縮めたい場合はGtkCellRendererオブジェクトの"ypad"プロパティを
g_object_set(renderer, "ypad", 0, NULL);
のように設定するとマージンを調整することができる。
長時間かかる処理中にUIの更新を行いたい場合は、通常は以下のように一時的にイベントループを回して処理する。
while (gtk_events_pending())
gtk_main_iteration();
しかし、これはすべてのイベントが処理されるまで待たされるため、例えばステータスバーのように一部分だけ表示が更新されればよい場合には無駄が大きい。
そこで、以下のようにすると特定のwidgetのみ表示を更新することができる。
if (GTK_WIDGET_VISIBLE(widget) && GTK_WIDGET_DRAWABLE(widget))
gdk_window_process_updates(widget->window, FALSE);
GtkStatusbarの右端にリサイズグリップを表示させることができるが、ステータスバーに複数のウィジェットを置いている場合はこれをうまく避けるようにしなければならない。
(追記: これはGTK+ 2.5.5以降で修正済み)
これはグリップのサイズを取得し、それと同じ横幅のGtkHBoxを右端に置いてやることで実現できる。
statusbar = gtk_statusbar_new();
spacer_hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_end(GTK_BOX(statusbar), spacer_hbox, FALSE, FALSE, 0);
gdk_drawable_get_size
(GDK_DRAWABLE(GTK_STATUSBAR(statusbar)->grip_window), &w, &h);
gtk_widget_set_size_request(spacer_hbox, w, -1);