C言語GUI入門|GTK 4プログラムとは

GTK 4プログラムは、C言語の基本的な仕組みにGTK 4のGUI機能を組み合わせたプログラムです。

通常のコンソールプログラムでは、main関数から処理を順番に実行し、結果をターミナルへ表示します。一方、GTK 4プログラムではウィンドウを表示したあと、マウスやキーボードからの操作を待ち続けます。

この記事では、GTK 4プログラムを構成する次の要素を、プログラムの一部を抜粋しながら確認します。

  • GTK 4プログラムの特徴
  • GTK 4の機能を利用するためのgtk/gtk.h
  • プログラムの開始地点となるmain関数
  • アプリケーション全体を管理するGtkApplication
  • 起動時に画面を準備するactivate関数
  • GTK 4プログラムの基本構造
  • ソースコードの記述順と実際の実行順

この記事に掲載するコードは構造を確認するためのもので、単独ではコンパイルや実行はできません。

GTK 4プログラムとは

GTK 4プログラムとは、GTK 4ライブラリを利用して、ウィンドウ、ボタン、入力欄、ラベルなどを画面に表示するプログラムです。

GTK 4では、GUI画面を構成する部品をウィジェットと呼びます。

代表的なウィジェットには、次のものがあります。

ウィジェット主な役割
GtkWindowアプリケーションのウィンドウを表示する
GtkLabel画面に文字を表示する
GtkButtonクリックできるボタンを表示する
GtkEntry文字を入力する欄を表示する
GtkBoxウィジェットを縦または横に並べる
GtkGridウィジェットを行と列に並べる

GTK 4プログラムでは、ウィンドウを作成し、その中へ必要なウィジェットを配置して画面を組み立てます。

例えば、ウィンドウの中にボタンを置く場合、ウィンドウが親ウィジェット、ボタンが子ウィジェットになります。このように、GTK 4の画面はウィジェットの親子関係によって構成されます。

コンソールプログラムとの違い

GTK 4プログラムも通常のC言語プログラムと同じように、main関数から実行が始まります。

ただし、プログラムの進み方には大きな違いがあります。

比較項目コンソールプログラムGTK 4プログラム
表示場所ターミナルウィンドウ
主な表示内容文字ウィジェット
処理の進み方上から順番に実行するイベントに応じて実行する
ユーザーの操作文字や数値を入力するマウスやキーボードで操作する
待機方法入力関数などで待つイベントループで待ち続ける
主な関数main関数main関数とコールバック関数
終了するタイミング最後の処理が終わったときウィンドウが閉じられたとき

コンソールプログラムでは、プログラマーが記述した順番に従って処理が進みます。

GTK 4プログラムでは、最初のウィンドウを表示したあと、GTK 4がユーザーの操作を待ちます。ボタンのクリックなどのイベントが発生すると、そのイベントに対応する関数が呼び出されます。

図1:コンソールプログラムとGTK 4プログラムの違い

この図から分かること

コンソールプログラムは、main関数から処理を順番に実行し、最後の処理が終わると終了します。

GTK 4プログラムもmain関数から始まりますが、ウィンドウを表示したあとはユーザーの操作を待ち続けます。

ボタンのクリックなどが発生すると、その操作に対応する処理を実行し、処理が終わると再び次の操作を待つ状態に戻ります。

GTK 4プログラムを構成する要素

基本的なGTK 4プログラムは、次の要素によって構成されます。

要素役割
gtk/gtk.hGTK 4の型、関数、マクロを利用できるようにする
main関数GtkApplicationを準備して実行する
GtkApplicationアプリケーション全体を管理する
activate関数起動時にウィンドウを準備する
シグナル出来事が発生したことを知らせる
コールバック関数シグナルに対応する処理を行う
イベントループユーザーの操作を待ち続ける

最初は、次の役割分担を覚えると分かりやすいでしょう。

  • main関数がアプリケーションを開始する
  • GtkApplicationがアプリケーション全体を管理する
  • activate関数が最初の画面を準備する

gtk/gtk.hとは

gtk/gtk.hは、GTK 4プログラムで必要になる型、関数、定数、マクロなどの宣言をまとめたヘッダファイルです。

GTK 4の機能を使用するソースファイルでは、先頭付近でgtk/gtk.hを読み込みます。

GTK 4のヘッダファイルを読み込む部分

ファイル名:hello_gtk.c

#include <gtk/gtk.h>

この1行によって、コンパイラが次のようなGTK 4の名前を理解できるようになります。

  • GtkApplication
  • GtkWidget
  • GtkWindow
  • GtkButton
  • GtkLabel
  • GTK 4が提供する関数
  • GTK 4が提供するマクロ

gtk/gtk.hを読み込まずにGtkApplicationなどを使用すると、コンパイラはその型を認識できません。そのため、型が定義されていないなどのコンパイルエラーが発生します。

stdio.hとの違い

第3章で作成したコンソールプログラムでは、stdio.hを読み込みました。

#include <stdio.h>

stdio.hとgtk/gtk.hには、次のような違いがあります。

ヘッダファイル主に利用する機能
stdio.hprintfなどの標準入出力機能
gtk/gtk.hウィンドウやボタンなどのGUI機能

stdio.hは、C言語の標準ライブラリに含まれています。

一方、gtk/gtk.hはC言語の標準機能ではありません。別途インストールしたGTK 4ライブラリが提供しています。

そのため、GTK 4プログラムをコンパイルするときは、通常のC言語プログラムとは異なるコンパイル設定が必要になります。

ヘッダファイルとライブラリの関係

gtk/gtk.hには、GTK 4の処理そのものがすべて記述されているわけではありません。

ヘッダファイルには、主に次の情報が記述されています。

  • 型の名前
  • 関数の名前
  • 関数が受け取る引数
  • 関数が返す値
  • 定数やマクロ

ウィンドウの作成やイベント処理などの実際の機能は、GTK 4ライブラリ側に用意されています。

要素役割
gtk/gtk.h型や関数の使い方をコンパイラへ知らせる
GTK 4ライブラリウィンドウ作成などの実際の機能を提供する
GCCソースファイルをコンパイルする
リンカープログラムとGTK 4ライブラリを結び付ける

main関数の役割

GTK 4プログラムも、main関数から実行が始まります。

ただし、main関数の中へウィンドウやボタンの作成処理をすべて書くわけではありません。

GTK 4プログラムのmain関数は、主に次の処理を担当します。

  1. GtkApplicationを準備する
  2. activateシグナルとactivate関数を関連付ける
  3. アプリケーションの実行を開始する
  4. ウィンドウが閉じられるまで待つ
  5. GtkApplicationを後片付けする
  6. アプリケーションの終了状態を返す

GTK 4プログラムのmain関数の形

ファイル名:hello_gtk.c

int main(int argc, char *argv[])
{
    /* GtkApplicationを準備する */

    /* activateシグナルとactivate関数を関連付ける */

    /* アプリケーションを実行する */

    /* GtkApplicationを後片付けする */

    /* アプリケーションの終了状態を返す */
}

このコードはmain関数の役割を示した抜粋です。コメント部分へ記述する具体的な関数は、次の記事で確認します。

argcとargvの役割

GTK 4プログラムのmain関数では、argcとargvを受け取る形がよく使われます。

int main(int argc, char *argv[])

それぞれの役割は次のとおりです。

名前役割
argcコマンドライン引数の個数を受け取る
argvコマンドライン引数を文字列として受け取る

GTK 4アプリケーションでは、main関数が受け取ったargcとargvをアプリケーションの実行処理へ渡します。

最初のプログラムでは、argcとargvを自分で細かく処理する必要はありません。まずは、アプリケーションの起動に必要な情報を受け取るものと考えれば十分です。

GtkApplicationとは

GtkApplicationは、GTK 4アプリケーション全体を管理するための型です。

GtkApplicationはウィンドウそのものではありません。ウィンドウを含めたアプリケーション全体の管理役です。

主に次のような処理に関係します。

  • アプリケーションの起動
  • アプリケーションの終了
  • ウィンドウの管理
  • イベント処理
  • コマンドライン引数の処理
  • アプリケーションIDの管理
  • OSのデスクトップ環境との連携

GtkApplicationを扱う変数の宣言部分

ファイル名:hello_gtk.c

GtkApplication *app;

このコードでは、GtkApplicationへのポインタを格納するappという変数を宣言しています。

部分意味
GtkApplicationGTKアプリケーションを表す型
*ポインタとして扱うことを表す
app変数名

GTK 4では、GtkApplication、ウィンドウ、ボタンなどをポインタで扱います。

現時点では、appはアプリケーション全体を管理するデータを指し示す変数と考えるとよいでしょう。

GtkApplicationとウィンドウの違い

GtkApplicationとウィンドウは、それぞれ異なる役割を持っています。

要素役割
GtkApplicationアプリケーション全体を管理する
ウィンドウユーザーに表示する画面を作る
ボタンユーザーのクリックを受け取る
ラベル画面に文字を表示する
入力欄キーボードから文字を受け取る

GtkApplicationを建物全体の管理者に例えると、ウィンドウは利用者が操作する部屋、ボタンや入力欄は部屋の中に置かれた道具のようなものです。

ひとつのGtkApplicationが、複数のウィンドウを管理することもできます。

activate関数とは

activate関数は、GTK 4アプリケーションが起動されたときに呼び出されるコールバック関数です。

一般的には、次のような画面の準備を担当します。

  • ウィンドウを作成する
  • ウィンドウのタイトルを設定する
  • ウィンドウの初期サイズを設定する
  • ボタンやラベルを作成する
  • ウィジェットを配置する
  • 完成したウィンドウを表示する

main関数がアプリケーションを開始する場所なら、activate関数は最初の画面を準備する場所です。

activate関数の形

ファイル名:hello_gtk.c

static void activate(GtkApplication *app, gpointer user_data)
{
    /* ウィンドウを作成する */

    /* ウィンドウの表示内容を設定する */

    /* ウィンドウを画面に表示する */
}

このコードも、activate関数の役割を確認するための抜粋です。

具体的なウィンドウ作成処理は、これから少しずつ追加していきます。

activate関数の構成

activate関数の宣言を部分ごとに分けると、次のようになります。

部分役割
staticこのソースファイル内で使用する関数にする
void関数が値を返さないことを表す
activate関数名
GtkApplication *app起動されたアプリケーションを受け取る
gpointer user_data必要に応じて追加データを受け取る

gpointerは、GTK 4の基盤となるGLibが提供する汎用的なポインタ型です。

最初のプログラムではuser_dataを使わないことがありますが、コールバック関数の決められた形に合わせて記述します。

図2:main関数とactivate関数の役割

この図から分かること

main関数では、GtkApplicationを準備してアプリケーションの実行を開始します。

アプリケーションが起動するとactivateシグナルが発生し、登録されているactivate関数が呼び出されます。

それぞれの役割は、次のように整理できます。

  • main関数はアプリケーションを開始する
  • GtkApplicationはアプリケーション全体を管理する
  • activate関数は最初の画面を準備する

activateはC言語の予約語ではない

activateはC言語の予約語ではありません。また、activateという名前の関数を作っただけでは、自動的に呼び出されません。

GTK 4プログラムでは、GtkApplicationのactivateシグナルと、作成したactivate関数を関連付けます。

処理の流れは次のようになります。

  1. main関数がGtkApplicationを準備する
  2. activateシグナルとactivate関数を関連付ける
  3. アプリケーションの実行を開始する
  4. GtkApplicationからactivateシグナルが発生する
  5. 関連付けられたactivate関数が呼び出される
  6. activate関数がウィンドウを準備する

重要なのはactivateという関数名そのものではなく、シグナルとコールバック関数が関連付けられていることです。

シグナルとコールバック関数

シグナルは、GTK 4からプログラムへ出来事の発生を知らせる仕組みです。

コールバック関数は、その出来事が発生したときにGTK 4から呼び出される関数です。

用語役割
シグナル出来事が発生したことを知らせる
コールバック関数出来事に対応する処理を行う
activateシグナルアプリケーションが起動されたことを知らせる
activate関数起動時に最初の画面を準備する

今後、ボタンを使用するときには、ボタンがクリックされたことを知らせるシグナルも登場します。

GTK 4プログラムは、このように出来事と処理する関数を関連付けながら作成します。

GTK 4プログラムの基本構造

ここまで確認したコードを並べると、GTK 4プログラムの基本構造をイメージできます。

GTK 4プログラム全体の構造を確認する抜粋

ファイル名:hello_gtk.c

#include <gtk/gtk.h>

static void activate(GtkApplication *app, gpointer user_data)
{
    /* ウィンドウを作成する */

    /* ウィンドウの表示内容を設定する */

    /* ウィンドウを画面に表示する */
}

int main(int argc, char *argv[])
{
    GtkApplication *app;

    /* GtkApplicationを作成する */

    /* activateシグナルとactivate関数を関連付ける */

    /* アプリケーションを実行する */

    /* GtkApplicationを後片付けする */

    /* アプリケーションの終了状態を返す */
}

この抜粋はGTK 4プログラムの構造を示したものです。処理の一部をコメントで表しているため、このままではコンパイルや実行はできません。

基本構造は、大きく3つの部分に分けられます。

部分内容
ヘッダ部分gtk/gtk.hを読み込む
activate関数ウィンドウを作成して表示する
main関数GtkApplicationを準備して実行する

記述順と実行順の違い

ソースファイルでは、一般的にactivate関数をmain関数より前に記述します。

しかし、プログラムはactivate関数から始まるわけではありません。C言語プログラムはmain関数から実行されます。

ソースファイルでの記述順

  1. gtk/gtk.hを読み込む
  2. activate関数を定義する
  3. main関数を定義する

実際の実行順

  1. main関数から実行が始まる
  2. GtkApplicationを作成する
  3. activateシグナルとactivate関数を関連付ける
  4. アプリケーションの実行を開始する
  5. activateシグナルが発生する
  6. activate関数が呼び出される
  7. ウィンドウを作成する
  8. ウィンドウを表示する
  9. ユーザーの操作を待つ

ソースファイルの上側にactivate関数が書かれていても、最初に実行されるのはmain関数です。

ウィンドウを表示したあとの動作

activate関数によってウィンドウが表示されると、GTK 4はイベントを待つ状態になります。

主なイベントには、次のものがあります。

  • マウスのクリック
  • キーボードからの入力
  • ウィンドウサイズの変更
  • ウィンドウの移動
  • 画面の再描画
  • ウィンドウを閉じる操作

GTK 4はイベントを受け取ると、対応するシグナルを発生させます。シグナルにコールバック関数が関連付けられていれば、その関数が呼び出されます。

処理が終わると、GTK 4は再び次のイベントを待ちます。この繰り返しをイベントループと呼びます。

ウィンドウを閉じたあとの動作

ユーザーがウィンドウを閉じると、アプリケーションの実行処理が終了し、main関数へ処理が戻ります。

main関数では、主に次の終了処理を行います。

  • アプリケーションの終了状態を受け取る
  • GtkApplicationを後片付けする
  • 終了状態を呼び出し元へ返す

GTK 4プログラムでは、ウィンドウを作成して表示するだけでなく、使用したオブジェクトを適切に後片付けすることも大切です。

図3:GTK 4プログラムの基本的な実行順

この図から分かること

GTK 4プログラムはmain関数から始まり、GtkApplicationによって管理されます。

アプリケーションを実行するとactivateシグナルが発生し、activate関数が呼び出されます。activate関数がウィンドウを表示したあとは、GTK 4がユーザーの操作を待ち続けます。

ウィンドウが閉じられるとアプリケーションの実行処理が終了し、main関数へ戻ります。その後、GtkApplicationを後片付けしてプログラムが終了します。

現時点で覚えておきたい役割

GTK 4の関数をすべて暗記する必要はありません。まずは、それぞれの役割を整理しておきましょう。

名前覚えておきたい役割
gtk/gtk.hGTK 4の型や関数を利用できるようにする
main関数アプリケーションの準備と実行を行う
GtkApplicationアプリケーション全体を管理する
activate関数起動時にウィンドウを準備する
シグナル出来事の発生を知らせる
コールバック関数出来事に対応する処理を行う
イベントループユーザーの操作を待ち続ける

次の記事「GtkApplicationを理解する」では、GtkApplicationを作成し、アプリケーションを実行して終了するまでに使用する関数を、プログラムの流れに沿って詳しく見ていきます。