次のコードを、お好きなエディタで記述して、hello.c という名前でお好きな場所に保存してください。Windowsの場合は、C:¥msys64¥home¥ユーザー名
に保存するのが便利です。
#include <gtk/gtk.h>
int main(int argc, char *argv[])
{
GtkWidget * window;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Hello");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show(window);
gtk_main();
return 0;
}
C:¥msys64¥home¥ユーザー名
に保存した場合は、MSYS2 を起動した画面が、
hello.c を保存した場所になります。
// macOS Linuxの場合
./a.out
./Hello
// Windowの場合
./a
./Hello
// ダブルクリックによる実行方法は後ほど説明します。
#include <gtk/gtk.h>
gtk/gtk.h を読み込むと、GTK 関連と C 関連のヘッダーファイルのほとんどを読み込めるみたいです。
int main(int argc, char *argv[])
main 関数では、C で定番となっている、int argc, char *argv[] という引数が 必須です。後ほどこれらの引数は使われます。
GtkWidget * window;
GtkWidget 型は、GTK ですべてのウィジェット(widget、GUIパーツ)を表す型です。
gtk_init(&argc, &argv);
gtk_init関数は、GTK アプリケーションを初期化する関数です。 この時に、main関数の引数を受け取ります。gtk_init関数は、 他のGTK関数を呼び出す前に呼び出さなければなりません
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_new関数は、ウィンドウを作る関数です。 引数のGTK_WINDOW_TOPLEVELは 0 を表す定数で、 ウィンドウにタイトルバーと境界線を表示するように指定します。 ここに 1 を指定すると、タイトルバーと境界線のないウィンドウが作成されます。
gtk_window_set_title(GTK_WINDOW(window), "Hello!");
}
gtk_window_set_title関数はウィンドウのタイトルを設定する関数です。 引数に対象のウィンドウと、タイトルを指定します。タイトルを指定しない場合は、 実行ファイル名がウィンドウのタイトルになります。
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_position関数はウィンドウの位置を設定する関数です。 引数に対象のウィンドウと、位置を指定するGTKの定数を指定します。 GTK_WIN_POS_CENTERは、ウィンドウをスクリーン中央に表示することを 指示する定数です。
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show(window);
gtk_widget_show関数は引数のウィジェットを表示します。 ウィンドウは作成しただけでは表示されません。この関数を呼び出して、 はじめて表示されます。
gtk_main();
イベントループを開始する関数です。アプリケーションはイベントループがなければ、 一瞬で終了します。一瞬で終了するためウィンドウの表示も見えません。
macOS では、アプリケーションを、「アプリケーションバンドル」とよばれる特殊なフォルダで管理します。アプリケーションバンドルを使うとダブルクリックでターミナルを開かずにアプリケーションを起動できるようになります。
アプリケーションバンドルは次のようなディレクトリ構成になります。
Hello.app
+Contents
++Info.plist
++MacOS
+++hello
++Resources
+++Hello.icns
Info.plist は、xml 形式のテキストファイルです。このファイルにアプリケーションのいろいろな設定をしていきます。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>hello</string>
<key>CFBundleIconFile</key>
<string>Hello.icns</string>
<key>CFBundleName</key>
<string>Hello</string>
<key>NSPrincipalClass</keyv
<string>NSApplication</string>
</dict>
</plist>
最小限、以上の5項目を設定すれば OK です
出来上がったアプリケーションバンドルをダブルクリックしても起動しない場合は、アプリケーションバンドルを他の場所(例えばデスクトップなど)に移動してダブルクリックしてみてください。一度起動できれば、そのあとは、どの場所に移動しても起動できます。
Fedora、CentOS、Ubuntu 16.04、Mint 18では、 コンパイルして出来上がった実行ファイルを、ダブルクリックで起動できます。 しかしアイコンはシステムのデフォルトアイコンになります。
Dbian、Ubuntu 18.04、Mint 19では、コンパイルして出来上がった実行ファイルを ダブルクリックしても起動できません。アイコンもつきません。
しかしスタートメニューに登録することで シングルクリックで起動できて任意のアイコンもつけることができます。
gcc hello.c `pkg-config --cflags --libs gtk+-3.0` -o hello
/usr/share/icons/hicolor/scalable/apps
/home/ユーザー名/.local/share/applications
[Desktop Entry]
Type=Application
Version=1.0
Name=Hello
Exec=/home/ユーザー名/.local/share/applications/hello
Icon=/home/ユーザー名/.local/share/applications/mate.svg
Comment=My first application.
Categories=
desktop-file-validate hello.desktop
上記の方法はユーザー専用にアプリケーションを登録する方法でした。 システム全体(全ユーザー向け)に登録するには、 それぞれのファイルの場所を次のとおり変更します。
デスクトップエントリー
~/.local/share/applications // ユーザー専用
/usr/share/applications // システム全体
アプリケーション
~/.local/shara/applications // ユーザー専用
/usr/bin // システム全体
アイコン
~/.local/share/applications // ユーザー専用
もしくは
~/.local/share/icons/hicolor/scalable/apps // ユーザー専用
/usr/share/icons/hicolor/scalable/apps // システム全体
デスクトップエントリーの設定を反映させるために次のコマンドを使えるそうですが、
私の環境でエラーが出ます。再ログインのほうが良いように思います。
再ログインなしで設定が反映される場合もあります。
update-desktop-database
そしてデスクトップエントリーを次のように変更します。
[Desktop Entry]
Type=Application
Version=1.0
Name=Hello
Exec=hello
Icon=mate.svg
Comment=My first application.
Categories=
/usr/binと/usr/share/icons/hicolor/scalable/appsには、 すでにパスが通っていますので、それぞれファイル名だけで大丈夫です。
ユーザー専用設定とシステム全体設定の両方が存在する場合は、 ユーザー専用設定が使われます。