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

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

C言語でGTK+ 2を扱う上での幾つかのメモ(第5回)

C言語でGTK+ 2を扱う上での幾つかのメモ(第4回)」の続き。

GObjectシグナル接続時の整数値のユーザデータのやりとりについて

関数g_signal_connect()でイベント(GObjectシグナル)とその発生時に呼ばれるハンドラ関数の関連付け(シグナルの接続)を行う際に、ハンドラ関数にはデータ(ユーザデータ)を渡すことができるのだが、このデータ型がgpointer(「void *」に等しい)つまり汎用ポインタと呼ばれているもの(任意の型のデータの「場所」を格納できる型)なので、もし「場所」ではなく整数の「値」をやりとりしたいのであれば、gpointer型と整数型とを専用のマクロにより相互に変換する。
例として、gint型のデータをユーザデータとして渡したいときには、シグナル接続時にはGINT_TO_POINTER()を用いて

g_signal_connect (G_OBJECT (obj), "signame", G_CALLBACK (handler), GINT_TO_POINTER (12345));

のようにし、ハンドラ側ではGPOINTER_TO_INT()で取り出す(戻り値がgint型の整数として扱える)。

/*
 * 注意: 「GtkXxx」という型はない
 *       ハンドラの戻り値の型はgboolean型の場合もある
 *       受け取る引数はGObjectシグナルによって異なる
 */
void
handler (GtkXxx *widget, gpointer user_data)
{
  gint x = GPOINTER_TO_INT (user_data);
}

やりとりするデータ型によって、マクロにも幾つかのバリエーションがある。

なお、このマクロは連結リスト(リスト構造)でデータに整数を用いる際にも使うことができ、以前「GLibで連結リスト(リスト構造)にデータを追加する方向とその時間について」で用いている。

GtkVBox/GtkHBox関係の関数の引数

PyGTKではスペースを分割する垂直ボックス(gtk.VBox)や水平ボックス(gtk.HBox)のクラスについて

  • コンストラクタ引数*1は初期値であれば省略可
  • GUI部品を先頭から入れるpack_start()や末尾から入れるpack_end()の対象のGUI部品(最初の引数)以外の引数*2は初期値であれば省略可

という特徴があった。

class gtk.Box(gtk.Container):
  def pack_start(child, expand=True, fill=True, padding=0)
  def pack_end(child, expand=True, fill=True, padding=0)

class gtk.VBox(gtk.Box):
  gtk.VBox(homogeneous=False, spacing=0)

class gtk.HBox(gtk.Box):
  gtk.HBox(homogeneous=False, spacing=0)

しかし、これはPyGTKの親切機能によるもので、C言語では引数は省略できない。

GtkWidget *gtk_vbox_new (gboolean homogeneous,
                         gint spacing);
GtkWidget *gtk_hbox_new (gboolean homogeneous,
                         gint spacing);

void gtk_box_pack_start (GtkBox *box,
                         GtkWidget *child,
                         gboolean expand,
                         gboolean fill,
                         guint padding);
void gtk_box_pack_end (GtkBox *box,
                       GtkWidget *child,
                       gboolean expand,
                       gboolean fill,
                       guint padding);

なお、Vala言語のGTK+ではGtk.VBoxクラスやGtk.HBoxクラスのコンストラクタ引数は省略できないが

public class VBox : Gtk.Box, Atk.Implementor, Gtk.Buildable, Gtk.Orientable {
  public VBox (bool homogeneous, int spacing);
}

public class HBox : Gtk.Box, Atk.Implementor, Gtk.Buildable, Gtk.Orientable {
  public HBox (bool homogeneous, int spacing);
}

メンバ関数pack_start(),pack_end()
中に入れるGUI部品(最初の引数)の後ろは初期値であれば省略できる。

public class Box : Gtk.Container, Atk.Implementor, Gtk.Buildable, Gtk.Orientable {
  public void pack_start (Gtk.Widget child, bool expand = true, bool fill = true, uint padding = 0);
  public void pack_end (Gtk.Widget child, bool expand = true, bool fill = true, uint padding = 0);

(「C言語でGTK+ 2を扱う上での幾つかのメモ(第6回)」に続く)

関連記事:

関連URL:

使用したバージョン:

  • GTK+ 2.18.3
  • PyGTK 2.16.0
  • Vala 0.9.2

*1:1番目:子を全て同じサイズに配置するかどうか 2番目:子どうしのスペース

*2:2番目:スペース一杯を占めるかどうか 3番目:一杯を占める場合に余白を作らずに広げるかどうか 4番目:子の両端に空けるスペース幅