[ C++で開発 ]

CygwinでGTK+を使う

GTK+はX Window System上のGUIツールキットの一つです。GNOMEデスクトップのベースとして使用されています。APIはC言語として提供されています。Windows用のGTK+には、Windowsへ移植されたGTK+(Cygwin不要)、CygwinのXFree86を導入し、そのXFree86上で実行可能なGTK+と、Cygwin上でXFree86なしにWindowsのGUIネイティブなGTK+があります。

GTK+のインストールと設定

Windows用のGTK+あれこれ

GTK+ for Windows

Microsoft Visual C++、MinGWなどで利用できるGTK+ライブラリが入手できます。

Runtime EnvironmentとDevelopment Environmentとソースコードがダウンロードできます。

GTK+ and GIMP for Windows

上と同じ?違う?

Win32ネイティブ版ライブラリです。

Cygwin用GTK+

Cygwin用にビルド・パッケージングされたGTK+ライブラリ一式が提供されています。

ネットインストールの場合、Other URLで"http://web.sfc.keio.ac.jp/~s01397ms/cygwin/"を指定してもインストールできます。

なお、CygwinでGKT+を動かすにあたって、Cygwinの以下のパッケージが必要とのことです。

GTK+のパッケージ

GTK+関係のパッケージはたくさんあってどれが必要なのか、依存関係がどうなっているのかわかりにくいです。

基本関係

Cygwin非X11環境でのGTK+

パッケージ名
glib-2.2.1-2.tar.gz gobject, gmodule glib
atk-1.2.0-1.tar.gz atk
pango-1.2.1-2.tar.gz pango, pangowin32
gtk2-win32-2.2.1-3.tar.gz gdk-win32, gdk_pixbuf, gtk
$ pkg-config --libs gtk+-win32-2.0
-Wl,--export-dynamic -lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 -lgdk_pixbuf-2.0
-lpangowin32-1.0 -lgdi32 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lin
tl -liconv -lm
$

CygwinX11環境でのGTK+

C++用API gtkmm

GTK+はC言語APIなので、C++から利用するときはちょっと面倒です。gtkmmは、GTK+をC++でラップするライブラリのひとつです。

Cygwin用のgtkmm

以下の2つのパッケージをインストールします。Cygwinのネットインストールで、Cygwin用GTK+と同じURLから入手できます。

動作確認

GTK+のインストールを確認するためにプログラムをコンパイル・リンクし実行していきます。

GTK+はじめの一歩

Hello World

hello-world.cの記述

hello-world.c
#include <gtk/gtk.h>

int main(int argc, char* argv[])
{
  GtkWidget* window;
  GtkWidget* label;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  label = gtk_label_new("Hello World.");

  gtk_container_add(GTK_CONTAINER(window), label);

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}

コンパイル

work$ ls
hello-world.c
work$ gcc -c hello-world.c `pkg-config gtk+-2.0 --cflags`
work$ ls
hello-world.c hello-world.o
work$ 

pkg-configを使ってコンパイルに必要なオプションを取り出して指定すると便利です。pkg-configは標準では/usr/lib/pkgconfig/の中にある設定ファイルを参照してコンパイル・リンク等に使用するオプションを取り出します。

$ pkg-config gtk+-2.0 --cflags
-I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/
include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include
$

リンク

work$ gcc -o hello-world hello-world.o `pkg-config gtk+-2.0 --libs`
work$ ls
hello-world.c hello-world.exe hello-world.o
work$ 

pkg-configを使ってリンクに必要なオプションを取り出して指定する便利です。

$ pkg-config gtk+-2.0 --libs
-Wl,--export-dynamic -lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 -lgdk_pixbuf-2.0
-lpangowin32-1.0 -lgdi32 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lin
tl -liconv -lm
$

実行

[×]ボタンを押してもウィンドウは消えますがプログラムは終了しません。

コールバックのあるHelloWorld

最初の例は、ユーザ操作イベントに対する反応がない単純な表示だけのプログラムでした。右上の[×]ボタンを押してもウィンドウ表示は消えますがプログラムは終了しないものでした。そこで、次は、コールバックによりユーザ操作に反応するプログラムの例を見てみます。ここでは、ボタンを使用するプログラムを作成します。

HelloButton.c
#include <gtk/gtk.h>

// ボタンが押されたら呼び出すコールバック関数のプロトタイプ宣言
static void callback_hello(GtkWidget* widget, gpointer data);

// ウィンドウ右上の[×]が押されたら呼び出すコールバック関数の
// プロトタイプ宣言
static gint callback_delete_event(GtkWidget* widget, GdkEvent* event,
                                  gpointer data);
// ウィンドウにdestroyイベントが生じたら呼び出すコールバック関数の
// プロトタイプ宣言
static void callback_destroy(GtkWidget* widget, gpointer data);

int main(int argc, char* argv[])
{
  GtkWidget* window;
  GtkWidget* button;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  // ウィンドウのdelete_eventが発行された場合([X]が押された)、
  // コールバック関数callback_delete_eventを呼ぶように設定
  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
                     GTK_SIGNAL_FUNC(callback_delete_event), NULL);

  // ウィンドウのdestroyイベントが発行された場合、
  // コールバック関数callback_destroyを呼ぶように設定
  gtk_signal_connect(GTK_OBJECT(window), "destroy",
                     GTK_SIGNAL_FUNC(callback_destroy), NULL);

  gtk_container_set_border_width(GTK_CONTAINER(window), 10);

  button = gtk_button_new_with_label("Hello World.");

  // ボタンのclickedイベントが発行された場合、
  // コールバック関数callback_helloを呼ぶように設定
  gtk_signal_connect(GTK_OBJECT(button), "clicked",
                     GTK_SIGNAL_FUNC(callback_hello), NULL);

  // ボタンがクリックされたら、ウィンドウに対してdestroyを発行する
  gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
                            GTK_OBJECT(window));

  gtk_container_add(GTK_CONTAINER(window), button);

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}

static void callback_hello(GtkWidget* widget, gpointer data)
{
  g_print("Hello, GTK+ World.\n");
}

static gint callback_delete_event(GtkWidget* widget, GdkEvent* event,
                                  gpointer data)
{
  g_print("deleteイベントが発生しました。\n");
  return TRUE;
}

static void callback_destroy(GtkWidget* widget, gpointer data)
{
  gtk_main_quit();
}

コンパイル、リンク、実行は上の例題とほぼ同じです。

GTKmm

インストール

Cygwin用GTK+のサイトに、バイナリパッケージが置かれています。gtkmmはlibsigc++に依存しているので、この2つをインストールします。


This page is written by Toru TAKAHASHI.(torutk@02.246.ne.jp)