GTK4   レイアウト

ホーム   C/C++チュートリアル  

レイアウト

ウィンドウには一つのウィジェットしか配置できません。これでは困るのでコンテナーと呼ばれるレイアウト専用 のウィジェットを使います。コンテナーには任意の数のウィジェットを配置できます。ウィンドウにコンテナーを 配置して、その上に(その中に)複数のウィジェットを配置していきます。コンテナーには様々なものがありますが、今回は Box と Grid を紹介します。

Box

以下のファイルを box.c という名前で記述してください。

box.c


/*************************************
    box.c
    copyright    :  vivacocoa.jp
    last modified:  Mar. 16, 2025
************************************/

#include <gtk/gtk.h>

static void
count (GtkButton *button, gpointer data)
{
	static int count = 0;
	char str[20];
	//g_print("%s\n",gtk_button_get_label(button));
	if (strcmp(gtk_button_get_label(button), "+")==0)
	{
		sprintf(str, "%d", ++count);
	} else {
		sprintf(str, "%d", --count);
	}
	gtk_label_set_text(data, str);
}
static void
activate (GtkApplication *app, gpointer data)
{
	GtkWidget *window;
	GtkWidget *vbox, *hbox;
	GtkWidget *label;
	GtkWidget *plus, *minus;
	
	window = gtk_application_window_new(app);
	gtk_window_set_title(GTK_WINDOW(window), "Box");
	gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
	
	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL,5);
	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
	gtk_window_set_child(GTK_WINDOW(window), vbox);
	
	label = gtk_label_new("0");
	//gtk_widget_set_size_request(label, 200, 133);
	gtk_widget_set_vexpand(label, 1);
	plus = gtk_button_new_with_label("+");
	minus = gtk_button_new_with_label("-");
	g_signal_connect(plus, "clicked", G_CALLBACK(count), label);
	g_signal_connect(minus, "clicked", G_CALLBACK(count), label);
	
	gtk_box_append(GTK_BOX(vbox), label);
	gtk_box_append(GTK_BOX(vbox), hbox);
	gtk_box_append(GTK_BOX(hbox), minus);
	gtk_box_append(GTK_BOX(hbox), plus);
	
	gtk_widget_set_hexpand(minus, 1);
	gtk_widget_set_hexpand(plus,  1);	
	
	gtk_window_present(GTK_WINDOW(window));
}
int
main (int argc, char **argv)
{
	GtkApplication *app;
	int status;
	app = gtk_application_new("jp.vivacocoa.box", G_APPLICATION_DEFAULT_FLAGS);
	g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
	status = g_application_run(G_APPLICATION(app), argc, argv);
	g_object_unref(app);
	return status;
}

コード説明

  1. vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL,5);
    ボックスというコンテナーウィジェットを作っています。コンテナーウィジェットは目に見えませが、その中に他のウィジェット を配置ですます。第1引数の GTK_ORIENTATION_VERTICA で上から順番に縦方向に他のウィジェットを配置できるように指定 しています。第2引数は、中に配置されたウィジェット同士の縦の隙間をピクセル単位で指定しています。
  2. hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
    第1引数の GTK_ORIENTATION_HORIZONTAL で左から順番に横方向に他のウィジェットを配置できるように指定しています。 第2引数の 5 で中に配置されたウィジェット同士の横の隙間を 5 ピクセルと指定しています
  3. gtk_window_set_child(GTK_WINDOW(window), vbox);
    ウィンドウに縦ボックスを配置しています。ウィンドウに配置された縦ボックスはウィンドウいっぱいに広がります。
  4. gtk_box_append(GTK_BOX(vbox), label);
    縦ボックスの上から1番目にラベルを配置しています。
  5. gtk_box_append(GTK_BOX(vbox), hbox);
    縦ボックスに上から2番目に横ボックスを配置しています
  6. gtk_box_append(GTK_BOX(hbox), minus);
    横ボックスの左から1番目に - ボタンを配置しています。
  7. gtk_box_append(GTK_BOX(hbox), plus);
    横ボックスの左から2番目に + ボタンを配置しています。
  8. gtk_widget_set_hexpand(minus, 1);
    - ボタンを横方向いっぱいに広げています。
  9. gtk_widget_set_hexpand(plus, 1);
    + ボタンを横方向いっぱいに広げています。

コンパイルと実行

以下のとおりです。Windows の場合は通常版でも ARM64版 でも mingw64 で行ってください。


// コンパイル
cc `pkg-config --cflags gtk4` box.c -o box `pkg-config --libs gtk4`

もしくは

gcc $(pkg-config --cflags gtk4) -o box box.c $(pkg-config --libs gtk4)

// 実行
./box

+ ボタンをクリックするとカウントアップして、- ボタンをクリックするとカウントダウンします。ウィンドウのサイズを変えても、レイアウトは崩れません。

Grid

以下のファイルを grid.c という名前で記述してください。

grid.c


/*************************************
    grid.c
    copyright    :  vivacocoa.jp
    last modified:  Mar. 16, 2025
************************************/

#include <gtk/gtk.h>

static void
count (GtkButton *button, gpointer data)
{
	static int count = 0;
	char str[20];
	//g_print("%s\n",gtk_button_get_label(button));
	if (strcmp(gtk_button_get_label(button), "+")==0)
	{
		sprintf(str, "%d", ++count);
	} else {
		sprintf(str, "%d", --count);
	}
	gtk_label_set_text(data, str);
}
static void
activate (GtkApplication *app, gpointer data)
{
	GtkWidget *window;
	GtkWidget *grid;
	GtkWidget *label;
	GtkWidget *plus, *minus;
	
	window = gtk_application_window_new(app);
	gtk_window_set_title(GTK_WINDOW(window), "Grid");
	gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
	grid = gtk_grid_new();
	gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
	//gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
	gtk_window_set_child(GTK_WINDOW(window), grid);
	label = gtk_label_new("0");
	gtk_widget_set_vexpand(label, TRUE);
	plus = gtk_button_new_with_label("+");
	minus = gtk_button_new_with_label("-");
	g_signal_connect(plus, "clicked", G_CALLBACK(count), label);
	g_signal_connect(minus, "clicked", G_CALLBACK(count), label);
	
	gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 2, 1);
	gtk_grid_attach(GTK_GRID(grid), minus, 0, 1, 1, 1);
	gtk_grid_attach(GTK_GRID(grid), plus,  1, 1, 1, 1);
	gtk_grid_set_column_spacing(GTK_GRID(grid),5);
	gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
	
	
	
	
	gtk_window_present(GTK_WINDOW(window));
}
int
main (int argc, char **argv)
{
	GtkApplication *app;
	int status;
	app = gtk_application_new("jp.vivacocoa.box", G_APPLICATION_DEFAULT_FLAGS);
	g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
	status = g_application_run(G_APPLICATION(app), argc, argv);
	g_object_unref(app);
	return status;
}

コード説明

  1. grid = gtk_grid_new();
    グリッドという格子状のコンテナーウィジェットを作っています。グリッドコンテナーは目に見えません。 グリッドの中には他のウィジェットを格子状に配置できます。
  2. gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
    グリッドの中に配置されたウィジョットの横の大きさを同じにするように設定しています。
  3. gtk_window_set_child(GTK_WINDOW(window), grid);
    ウィンドウにグリッドを配置しています。ウィンドウに配置されたグリッドはウィンドウいっぱいに広がります。
  4. gtk_widget_set_vexpand(label, TRUE);
    まだ配置していませんが、ラベルが縦いっぱいに広がるように設定しています。これでラベルの中の文字は上下の高さの 中央に配置されることになります。
  5. gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 2, 1);
    グリッドの中にラベルを配置しています。最初の 0 が、左から1番目を表し、2番目の 0 が、縦方向の 1 番目を表しています。3番目の 2 は、横方向に格子のマス目を 2 個使うことを表し、 4番目の 1 が縦方向に格子のマス目を 1 個使うことを表しています。
  6. gtk_grid_attach(GTK_GRID(grid), minus, 0, 1, 1, 1);
    グリッドに - ボタンを配置しています。位置は左から1番目 (0)、上から2番目 (1)で、使用する格子は縦横ともに 1 個です。
  7. gtk_grid_attach(GTK_GRID(grid), plus, 1, 1, 1, 1);
    グリッドに + ボタンを配置しています。位置は左から2番目 (1)、上から2番目 (1)で、使用する格子は縦横ともに 1 個です。
  8. gtk_grid_set_column_spacing(GTK_GRID(grid),5);
    グリッドの中のウィジョット同士の横の隙間を 5 ピクセルに設定しています。
  9. gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
    グリッドの中のウィジェット同士の縦の隙間を 5 ピクセルに設定しています。

コンパイルと実行

以下のとおりです。Windows の場合は通常版でも ARM64版 でも mingw64 で行ってください。


// コンパイル
cc `pkg-config --cflags gtk4` grid.c -o grid `pkg-config --libs gtk4`

もしくは

gcc $(pkg-config --cflags gtk4) -o grid grid.c $(pkg-config --libs gtk4)

// 実行
./grid

+ ボタンをクリックするとカウントアップして、- ボタンをクリックするとカウントダウンします。ウィンドウのサイズを変えても、レイアウトは崩れません。


234 visits
Posted: Mar. 16, 2025
Update: Mar. 21, 2025

ホーム   C/C++チュートリアル   目次