【Linux】C言語でGUIプログラミング【GTK+】
このドキュメントは,Unix/Linux上のC言語でGUIプログラミングを行う方法について,掻い摘んで説明しています。 環境に関しては,OSはLinux(Debian/Ubuntu系), コンパイラはgcc,GUIツールキットはGTK+2.0,を使用します。 しかし,GTK+の開発環境を導入すれば,他のOSでもこのドキュメントのプログラムを利用することができます。
趣旨としては,「GUIプログラミングはこんな感じでやるんだぜ」という雰囲気を味わってもらいたいだけですので, プログラミングや,GTK+の細かい使い方については触れません。その手の情報に関しては,ページ中に解説サイトへの リンクを貼ってありますので,そちらをご覧ください。
このページの便利な読み方について説明します。 各見出しの横に「↑」マークがあります。これをクリックすると,目次にもどることができます。 また,コード部分をダブルクリックすると,そのコード全体を選択する事ができます。この状態でコピーすると,プログラムを簡単に入手できます。 (必ずjavascriptを使えるブラウザで見てください。)
全てのプログラムを一括してダウンロードしたい場合は,次のリンクをクリックしてください。
howto-gtk.zipのダウンロード
GTK+はC言語用のライブラリですが,C++やPythonなど,他言語でのバインディングも存在するため, 幅広く利用することができます。
GTK+を使用して作られたソフトとしては,GIMP,Gnome,Mozilla Firefox などがあります。詳しくは WikipediaのGTK+のページ でも読んでください。
GTK+関係のオススメサイトとしては,次のようなサイトがあります。
Linuxを実行しながら、私はWindowsのファイルを使用することができます
- GTK/GNOMEによるGUIプログラミング
名著『入門GTK+』の著者のサイトです。
リンク先の「配布物」で『入門GTK+』のpdf版が読めます。(現在,10章中6章まで公開されています。) - GTK::超入門
日本語の入門サイトです。検索機能を活用すると,目的の情報を得られやすいです。 - GTK Tutorial(日本語版)
本家チュートリアルを有志が和訳した物です。
画像がほとんどないので,イメージがわきにくいのが難点だと思います。 - GTK+ 2.0 Tutorial(英語)
開発本家の初心者向けチュートリアルです。
上記サイトの元になったサイトです。 - GTK+ - Documentation(英語)
開発本家のDocumentationのページです。
上記のチュートリアルや,もっと詳しいリファレンス,解説サイトへのリンク集などがあります。 - GNOME ドキュメントライブラリ(英語)
GNOMEやGTK+,それに関係が深いライブラリに関する情報をまとめた総合サイトです。
APIリファレンスなどもあり,構造体や関数などの詳しい情報が知りたいなら,頻繁にアクセスすることになるでしょう。 英語が中心ですが,時々日本語があります。
GTK+,Gladeのインストール
まずは,GTK+を使えるようにしましょう。 今回は,統合開発環境は使わず,テキストエディタで作っていくことにします。 ただし,GUIデザイナーであるGladeの使い方は説明します。開発環境はパッケージマネージャで簡単に整えられます。 Debian/Ubuntu系のLinuxの場合は,次のコマンドを実行するだけです。
$ sudo apt-get install libgtk2.0-dev glade
Debian/Ubuntu系以外のLinuxでも,大抵の場合パッケージマネージャからインストールできると思います。 ただ,パッケージ名やバージョンが異なると思うので,気をつけてインストールしてください。最後に,正しくインストールされているかどうか確認しましょう。 次のコマンドを実行して,"No package 'gtk+-2.0' found"のようなメッセージが表示されなければ正しくインストールできています。正常にインストールされている場合,次のような呪文が表示されます。(呪文の意味は気にしないでください)
$ pkg-config --cflags gtk+-2.0
-pthread -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng14
コンパイル方法
GTK+を使用しているプログラムtest.cがあるとします。 これをコンパイルするには,次のコマンドを使います。$ gcc $(pkg-config --cflags --libs gtk+-2.0) test.c -o test
上記のコマンドを毎回書くのは大変ですので,エイリアスをします。 次のコマンドを実行してください。
$ alias gtp='gcc $(pkg-config --cflags --libs gtk+-2.0)'
すると,$ gtp test.c -o test
私はVisual Studioを実行するには、 Vistaのどのバージョンが必要ですかとするだけで,コンパイルできるようになります。
上記のエイリアスコマンドを,${HOME}/.bashrcの末尾に書いておけば, 次にターミナルを立ち上げた時もgtpコマンドが使えるようになります。
この章では,簡単なGUIプログラムをつくります。 内容としては,『入門GTK+』の第2章のはじめの方を簡略化した感じです。ウインドウを表示する
とりあえず,空のウインドウを表示してみましょう。CUIプログラムにおけるHello Worldと同じです。 次のプログラムをコンパイルして,実行してください。 コンパイルと実行。 $ gcc $(pkg-config --cflags --libs gtk+-2.0) window01.c -o window01
$ ./window01
(私は奇妙なウインドウマネージャを使っているので,閉じるボタン等がありませんが,普通のウインドウマネージャでは,それらがあると思います。)
ウインドウにボタンをつける
次に,ウインドウにボタンをつけてみましょう。追加部分は,背景色を変えてあります。 実行すると,次のように表示されます。 これは,1個のボタンがウインドウ全体に広がっています。 ボタンをクリックすると,プログラムが終了します。ウインドウに画像を表示する
続いて画像を表示してみましょう。プログラムと同じディレクトリ(フォルダ)に, girl.pngというファイルが存在していることを確認してから実行してください。girl.pngのダウンロード
実行すると,次のようになります。(イラストの転載や再配布は禁止です。)
プログラムのコメントにある「パッキンボックス」というのは,htmlでいう所のテーブルのような物です。 これを使うと,ウインドウ上に複数のウィジェットを配置することができます。
そのため,パッキンボックスを使うと,ウィジェットを好きなように配置できます。 これによりどのようなインタフェースも作成できます。
しかし,私自身はあまりこのような方法でGUIを作りません。 もっと直感的にGUIを作成する方法があります。それは,GUIデザイナーと呼ばれるツールを使用する方法です。 これについては次章でお話します。
Gladeとは何か
GladeはGTK用のGUIデザイナーです。これを使うと,ペイントソフトのような感覚でGUIを作れます。 Gladeはバージョンによって,使い方が異なりますが,ここではGlade 3系の使い方を説明します。
Gladeは作成したGUIを,".glade"という拡張子で出力します。gladeファイルの実体はxmlです。 これをプログラムに読み込む事で,作成したGUIを動かすことができます。
それでは,さっそく使ってみましょう。ここでは,前節「ウインドウに画像を表示する」と同じ物をつくります。
Gladeの解説サイトとしては,次のサイトを読んでください。(どちらも英語です)Gladeの使い方
Gladeを起動すると,次のようなウインドウが表示されます。とりあえず「閉じる」ボタンをクリックしてください。
次に,ウインドウボタンをクリックします。 すると,画面にウインドウが作られます。
Ubuntuのランプサーバー上のデスクトップをインストールする方法
続いて,横パッキンボックスを作りましょう。 ツールから横パッキンボックスを選び,ウインドウ上でクリックします。
すると,アイテム数を聞いてきますので,「2」にします。
今度は,ボタンと画像を読み込むためのフィールドを取り付けます。 ツールからボタンと画像を選んで,パッキンボックス上でクリックしてください。
最後にプロパティの設定をします。プロパティの設定は右側のインスペクターとプロパティを使います。
今,インスペクターの「ウィジェット」には,次のウィジェットがあります。
- window1
- vbox1
- image1
- button1
- window1 → window
- vbox1 → vbox
- image1 → image
- button1 → button
次に,インスペクターでwindowを選択して,「プロパティ」の「全般タブ」内の, 「デフォルトの幅」「デフォルトの高さ」を,それぞれ300, 400にします。
buttonのプロパティで,「パッキング」タブの「拡張」を「いいえ」にします。
「全般」タブで,「画像がついたラベル」から「ストックボタン」にチェックを入れ替えます。 そして,「ストックボタン:」で「終了(Q)」を選びます。
「シグナル」の「GtkButton」内の「cliked」で,「ハンドラ名」に「on_button_clicked()」を選択します。
最後に,imageのプロパティを変更します。 「シグナル」の「GtkButton」内の「expose-event」で,「ハンドラ名」に「image_expose_event_cb()」を選択します。
以上の設定を行うと,ウインドウが次のようになります。ボタンがそれらしくなりましたね。
Gladeファイルを用いたプログラム
先程Gladeで作成したGUIを,C言語で読み込んで,プログラムとして完成させましょう。 今回も理屈は抜きにして,プログラムを書きます。理屈を説明しないのは,「こうすれば動くんだな」くらいの気持ちでプログラムを読んでほしいからです。 本音を言えば私が詳しく知らないからです(^^;)
下記のプログラムは,Glade3 tutorial (6) - Signalsを参考にして書いていますので,詳しい解説が欲しい方は,こちらを読んでください。
Gladeファイルを使うときは,コンパイルのコマンドが違います。次のコマンドを使ってください。
$ gcc $(pkg-config --cflags --libs gtk+-2.0 gmodule-2.0) glade01.c -o glade01
では,ディレクトリ内に次のファイルが存在していること確認して,実行してください。
- glade01.c
- gui.glade
- girl.png
- glade01(ビルドして生成された実行ファイル)
今回作成したプログラムでは,「ウインドウに画像を表示する」よりも複雑なプログラムになってしまいました。 しかし,もっと実用性のあるソフトウェアを作ろうとした場合,GUIデザイナーを使った方が,圧倒的に楽になります。
図形の描画
GTK+で図形を描画するには,GTK+に含まれているcairoというライブラリを使います。 cairoはベクター形式の画像を表示するためのライブラリです。ドローソフトのInkscapeでできることは,だいたいcairoでもできると考えてもらえればいいです。cairoについては,次のようなサイトを参考にしてください。
御託は嫌いなので,とりあえず,プログラムを書きましょう。 このプログラムを実行すると,次のようになります。
イベントループ
大抵の場合,ゲームのプログラムでは,イベントループとかメインループなど呼ばれるループをつくります。 イベントループは,0.1秒とか0.01秒ぐらいの周期で実行されます。 これはCPUのクロックと同じようなもので,イベントループが動くタイピングにあわせてゲーム全体が動きます。今回はブロック崩しなので,「ボールを動かす」「ボールがブロックにあたったか判定する」「キーボード入力を反映する」などといった処理をイベントループで行います。
このプログラムを実行すると,次のようになります。 1秒毎に数字が変わります。ボールを動かす
先程作成したイベントループを使ってボールを動かしてみましょう。 上記のプログラムを実行すると次のようになります。(下の画像ではgifアニメ用にウインドウサイズを小さめにしてます。)上記のプログラムでは,10ミリ秒おきにcb_expose_event()が呼び出されます。 呼び出されるたびに,ボールの位置を示すパラメータ(t_x, t_y)の値が変わるので, ボールが動いているように見えます。
キーボード入力を調べる
今回のブロック崩しゲームでは,パッドをテンキーの「←」「→」で操作することにします。 そのため,キーボードからの入力を取得する必要があります。 そこで,次のプログラムを使います。 実行すると,次のようになります。ウインドウに意味はありませんが, ウインドウにフォーカスがある状態で,テンキーの「←」「→」が押すと, ターミナルに"left", "right"が表示されます。テキストの表示
ゲームの終了時に,「ゲームオーバ」や「ゲームクリア」といった文字を表示したいので, そのためのプログラムを作ります。ただし,下記の方法はcairoによるテキストの表示方法であって, ツールソフトなどをつくる際にはlabelウィジェットというテキスト表示専用のウィジェットを使ったほうがいいです。
ブロック崩しゲーム
さすがにちょっと長くなりましたが,プログラム中のコメントと一緒にコードを読んでいただければ, だいたいわかると思います(^^;)関数cb_expose_event()が,ゲーム全体の流れをコントロールしているので,ここを中心に読めば わかりやすいと思います。(背景色が違う部分です)
java等でゲームを作ったことのある人なら,このプログラムにダブルバッファリングに関する 記述がないことを不思議に思うかもしれません。
GTK+の場合,ダブルバッファリングは自動でやってくれます。
実行すると,次のようになります。
0 コメント:
コメントを投稿