Gtk4-tutorial/docs/sec4.html

359 lines
26 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>Gtk4 tutorial</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
pre{overflow: visible;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::after
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
th {padding: 2px 6px; border: 1px solid; background-color: ghostwhite;}
td {padding: 2px 6px; border: 1px solid;}
img {display: block; margin-left: auto; margin-right: auto;}
figcaption {text-align: center;}
</style>
</head>
<body style="padding-top: 70px;">
<div class="container">
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
<div class="container-fluid">
<span class="navbar-brand">Gtk4 tutorial</span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="index.html">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="sec3.html">Prev: section3</a>
</li>
<li class="nav-item">
<a class="nav-link" href="sec5.html">Next: section5</a>
</li>
</ul>
</div>
</div>
</nav>
<h1 id="widgets-1">Widgets (1)</h1>
<h2 id="gtklabel-gtkbutton-and-gtkbox">GtkLabel, GtkButton and Gtkbox</h2>
<h3 id="gtklabel">GtkLabel</h3>
<p>In the previous section we made a window and displayed it on the screen. Now we go on to the next topic, where we add widgets to this window. The simplest widget is GtkLabel. It is a widget with text in it.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1"></a><span class="pp">#include </span><span class="im">&lt;gtk/gtk.h&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2"></a></span>
<span id="cb1-3"><a href="#cb1-3"></a><span class="dt">static</span> <span class="dt">void</span></span>
<span id="cb1-4"><a href="#cb1-4"></a>app_activate (GApplication *app, gpointer user_data) {</span>
<span id="cb1-5"><a href="#cb1-5"></a> GtkWidget *win;</span>
<span id="cb1-6"><a href="#cb1-6"></a> GtkWidget *lab;</span>
<span id="cb1-7"><a href="#cb1-7"></a></span>
<span id="cb1-8"><a href="#cb1-8"></a> win = gtk_application_window_new (GTK_APPLICATION (app));</span>
<span id="cb1-9"><a href="#cb1-9"></a> gtk_window_set_title (GTK_WINDOW (win), <span class="st">&quot;lb1&quot;</span>);</span>
<span id="cb1-10"><a href="#cb1-10"></a> gtk_window_set_default_size (GTK_WINDOW (win), <span class="dv">400</span>, <span class="dv">300</span>);</span>
<span id="cb1-11"><a href="#cb1-11"></a></span>
<span id="cb1-12"><a href="#cb1-12"></a> lab = gtk_label_new (<span class="st">&quot;Hello.&quot;</span>);</span>
<span id="cb1-13"><a href="#cb1-13"></a> gtk_window_set_child (GTK_WINDOW (win), lab);</span>
<span id="cb1-14"><a href="#cb1-14"></a></span>
<span id="cb1-15"><a href="#cb1-15"></a> gtk_widget_show (win);</span>
<span id="cb1-16"><a href="#cb1-16"></a>}</span>
<span id="cb1-17"><a href="#cb1-17"></a></span>
<span id="cb1-18"><a href="#cb1-18"></a><span class="dt">int</span></span>
<span id="cb1-19"><a href="#cb1-19"></a>main (<span class="dt">int</span> argc, <span class="dt">char</span> **argv) {</span>
<span id="cb1-20"><a href="#cb1-20"></a> GtkApplication *app;</span>
<span id="cb1-21"><a href="#cb1-21"></a> <span class="dt">int</span> stat;</span>
<span id="cb1-22"><a href="#cb1-22"></a></span>
<span id="cb1-23"><a href="#cb1-23"></a> app = gtk_application_new (<span class="st">&quot;com.github.ToshioCP.lb1&quot;</span>, G_APPLICATION_FLAGS_NONE);</span>
<span id="cb1-24"><a href="#cb1-24"></a> g_signal_connect (app, <span class="st">&quot;activate&quot;</span>, G_CALLBACK (app_activate), NULL);</span>
<span id="cb1-25"><a href="#cb1-25"></a> stat =g_application_run (G_APPLICATION (app), argc, argv);</span>
<span id="cb1-26"><a href="#cb1-26"></a> g_object_unref (app);</span>
<span id="cb1-27"><a href="#cb1-27"></a> <span class="cf">return</span> stat;</span>
<span id="cb1-28"><a href="#cb1-28"></a>}</span></code></pre></div>
<p>Save this program to a file <code>lb1.c</code>. Then compile and run it.</p>
<pre><code>$ comp lb1
$ ./a.out</code></pre>
<p>A window with a message “Hello.” appears.</p>
<figure>
<img src="../image/screenshot_lb1.png" alt="" /><figcaption>Screenshot of the label</figcaption>
</figure>
<p>Theres only a little change between <code>pr4.c</code> and <code>lb1.c</code>. A program <code>diff</code> is good to know the difference between two files.</p>
<pre><code>$ cd misc; diff pr4.c lb1.c
5a6
&gt; GtkWidget *lab;
8c9
&lt; gtk_window_set_title (GTK_WINDOW (win), &quot;pr4&quot;);
---
&gt; gtk_window_set_title (GTK_WINDOW (win), &quot;lb1&quot;);
9a11,14
&gt;
&gt; lab = gtk_label_new (&quot;Hello.&quot;);
&gt; gtk_window_set_child (GTK_WINDOW (win), lab);
&gt;
18c23
&lt; app = gtk_application_new (&quot;com.github.ToshioCP.pr4&quot;, G_APPLICATION_FLAGS_NONE);
---
&gt; app = gtk_application_new (&quot;com.github.ToshioCP.lb1&quot;, G_APPLICATION_FLAGS_NONE);</code></pre>
<p>This tells us:</p>
<ul>
<li>The definition of a new variable <code>lab</code> is added.</li>
<li>The title of the window is changed.</li>
<li>A label is created and connected to the window as a child.</li>
</ul>
<p>The function <code>gtk_window_set_child (GTK_WINDOW (win), lab)</code> makes the label <code>lab</code> a child widget of the window <code>win</code>. Be careful. A child widget is different from a child object. Objects have parent-child relationships and widgets also have parent-child relationships. But these two relationships are totally different. Dont be confused. In the program <code>lb1.c</code>, <code>lab</code> is a child widget of <code>win</code>. Child widgets are always located in their parent widget on the screen. See how the window has appeared on the screen. The application window includes the label.</p>
<p>The window <code>win</code> doesnt have any parents. We call such a window top-level window. An application can have more than one top-level window.</p>
<h3 id="gtkbutton">GtkButton</h3>
<p>The next widget to introduce is GtkButton. It displays a button on the screen with a label or icon on it. In this subsection, we will make a button with a label. When the button is clicked, it emits a “clicked” signal. The following program shows how to catch the signal to then do something.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1"></a><span class="pp">#include </span><span class="im">&lt;gtk/gtk.h&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2"></a></span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="dt">static</span> <span class="dt">void</span></span>
<span id="cb4-4"><a href="#cb4-4"></a>click_cb (GtkButton *btn, gpointer user_data) {</span>
<span id="cb4-5"><a href="#cb4-5"></a> g_print (<span class="st">&quot;Clicked.</span><span class="sc">\n</span><span class="st">&quot;</span>);</span>
<span id="cb4-6"><a href="#cb4-6"></a>}</span>
<span id="cb4-7"><a href="#cb4-7"></a></span>
<span id="cb4-8"><a href="#cb4-8"></a><span class="dt">static</span> <span class="dt">void</span></span>
<span id="cb4-9"><a href="#cb4-9"></a>app_activate (GApplication *app, gpointer user_data) {</span>
<span id="cb4-10"><a href="#cb4-10"></a> GtkWidget *win;</span>
<span id="cb4-11"><a href="#cb4-11"></a> GtkWidget *btn;</span>
<span id="cb4-12"><a href="#cb4-12"></a></span>
<span id="cb4-13"><a href="#cb4-13"></a> win = gtk_application_window_new (GTK_APPLICATION (app));</span>
<span id="cb4-14"><a href="#cb4-14"></a> gtk_window_set_title (GTK_WINDOW (win), <span class="st">&quot;lb2&quot;</span>);</span>
<span id="cb4-15"><a href="#cb4-15"></a> gtk_window_set_default_size (GTK_WINDOW (win), <span class="dv">400</span>, <span class="dv">300</span>);</span>
<span id="cb4-16"><a href="#cb4-16"></a></span>
<span id="cb4-17"><a href="#cb4-17"></a> btn = gtk_button_new_with_label (<span class="st">&quot;Click me&quot;</span>);</span>
<span id="cb4-18"><a href="#cb4-18"></a> gtk_window_set_child (GTK_WINDOW (win), btn);</span>
<span id="cb4-19"><a href="#cb4-19"></a> g_signal_connect (btn, <span class="st">&quot;clicked&quot;</span>, G_CALLBACK (click_cb), NULL);</span>
<span id="cb4-20"><a href="#cb4-20"></a></span>
<span id="cb4-21"><a href="#cb4-21"></a> gtk_widget_show (win);</span>
<span id="cb4-22"><a href="#cb4-22"></a>}</span>
<span id="cb4-23"><a href="#cb4-23"></a></span>
<span id="cb4-24"><a href="#cb4-24"></a><span class="dt">int</span></span>
<span id="cb4-25"><a href="#cb4-25"></a>main (<span class="dt">int</span> argc, <span class="dt">char</span> **argv) {</span>
<span id="cb4-26"><a href="#cb4-26"></a> GtkApplication *app;</span>
<span id="cb4-27"><a href="#cb4-27"></a> <span class="dt">int</span> stat;</span>
<span id="cb4-28"><a href="#cb4-28"></a></span>
<span id="cb4-29"><a href="#cb4-29"></a> app = gtk_application_new (<span class="st">&quot;com.github.ToshioCP.lb2&quot;</span>, G_APPLICATION_FLAGS_NONE);</span>
<span id="cb4-30"><a href="#cb4-30"></a> g_signal_connect (app, <span class="st">&quot;activate&quot;</span>, G_CALLBACK (app_activate), NULL);</span>
<span id="cb4-31"><a href="#cb4-31"></a> stat =g_application_run (G_APPLICATION (app), argc, argv);</span>
<span id="cb4-32"><a href="#cb4-32"></a> g_object_unref (app);</span>
<span id="cb4-33"><a href="#cb4-33"></a> <span class="cf">return</span> stat;</span>
<span id="cb4-34"><a href="#cb4-34"></a>}</span></code></pre></div>
<p>Look at the line 17 to 19. First, it creates a GtkButton instance <code>btn</code> with a label “Click me”. Then, adds the button to the window <code>win</code> as a child. Finally, connects a “clicked” signal of the button to a handler (function) <code>click_cb</code>. So, if <code>btn</code> is clicked, the function <code>click_cb</code> is invoked. The suffix “cb” means “call back”.</p>
<p>Name the program <code>lb2.c</code> and save it. Now compile and run it.</p>
<figure>
<img src="../image/screenshot_lb2.png" alt="" /><figcaption>Screenshot of the label</figcaption>
</figure>
<p>A window with the button appears. Click the button (it is a large button, you can click everywhere in the window), then a string “Clicked.” appears on the terminal. It shows the handler was invoked by clicking the button.</p>
<p>Its good that we make sure that the clicked signal was caught and the handler was invoked by using <code>g_print</code>. However, using g_print is out of harmony with Gtk which is a GUI library. So, we will change the handler. The following code is <code>lb3.c</code>.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb5-1"><a href="#cb5-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
<span id="cb5-2"><a href="#cb5-2"></a>click_cb (GtkButton *btn, gpointer user_data) {</span>
<span id="cb5-3"><a href="#cb5-3"></a> GtkWindow *win = GTK_WINDOW (user_data);</span>
<span id="cb5-4"><a href="#cb5-4"></a> gtk_window_destroy (win);</span>
<span id="cb5-5"><a href="#cb5-5"></a>}</span>
<span id="cb5-6"><a href="#cb5-6"></a></span>
<span id="cb5-7"><a href="#cb5-7"></a><span class="dt">static</span> <span class="dt">void</span></span>
<span id="cb5-8"><a href="#cb5-8"></a>app_activate (GApplication *app, gpointer user_data) {</span>
<span id="cb5-9"><a href="#cb5-9"></a> GtkWidget *win;</span>
<span id="cb5-10"><a href="#cb5-10"></a> GtkWidget *btn;</span>
<span id="cb5-11"><a href="#cb5-11"></a></span>
<span id="cb5-12"><a href="#cb5-12"></a> win = gtk_application_window_new (GTK_APPLICATION (app));</span>
<span id="cb5-13"><a href="#cb5-13"></a> gtk_window_set_title (GTK_WINDOW (win), <span class="st">&quot;lb3&quot;</span>);</span>
<span id="cb5-14"><a href="#cb5-14"></a> gtk_window_set_default_size (GTK_WINDOW (win), <span class="dv">400</span>, <span class="dv">300</span>);</span>
<span id="cb5-15"><a href="#cb5-15"></a></span>
<span id="cb5-16"><a href="#cb5-16"></a> btn = gtk_button_new_with_label (<span class="st">&quot;Quit&quot;</span>);</span>
<span id="cb5-17"><a href="#cb5-17"></a> gtk_window_set_child (GTK_WINDOW (win), btn);</span>
<span id="cb5-18"><a href="#cb5-18"></a> g_signal_connect (btn, <span class="st">&quot;clicked&quot;</span>, G_CALLBACK (click_cb), win);</span>
<span id="cb5-19"><a href="#cb5-19"></a></span>
<span id="cb5-20"><a href="#cb5-20"></a> gtk_widget_show (win);</span>
<span id="cb5-21"><a href="#cb5-21"></a>}</span></code></pre></div>
<p>And the difference between <code>lb2.c</code> and <code>lb3.c</code> is as follows.</p>
<pre><code>$ cd misc; diff lb2.c lb3.c
5c5,6
&lt; g_print (&quot;Clicked.\n&quot;);
---
&gt; GtkWindow *win = GTK_WINDOW (user_data);
&gt; gtk_window_destroy (win);
14c15
&lt; gtk_window_set_title (GTK_WINDOW (win), &quot;lb2&quot;);
---
&gt; gtk_window_set_title (GTK_WINDOW (win), &quot;lb3&quot;);
17c18
&lt; btn = gtk_button_new_with_label (&quot;Click me&quot;);
---
&gt; btn = gtk_button_new_with_label (&quot;Quit&quot;);
19c20
&lt; g_signal_connect (btn, &quot;clicked&quot;, G_CALLBACK (click_cb), NULL);
---
&gt; g_signal_connect (btn, &quot;clicked&quot;, G_CALLBACK (click_cb), win);
29c30
&lt; app = gtk_application_new (&quot;com.github.ToshioCP.lb2&quot;, G_APPLICATION_FLAGS_NONE);
---
&gt; app = gtk_application_new (&quot;com.github.ToshioCP.lb3&quot;, G_APPLICATION_FLAGS_NONE);
35d35
&lt; </code></pre>
<p>The changes are:</p>
<ul>
<li>The function <code>g_print</code> in <code>lb2.c</code> was deleted and the two lines above are inserted instead.</li>
<li>The label of <code>btn</code> is changed from “Click me” to “Quit”.</li>
<li>The fourth argument of <code>g_signal_connect</code> is changed from <code>NULL</code> to <code>win</code>.</li>
</ul>
<p>The most important change is the fourth argument of <code>g_signal_connect</code>. This argument is described as “data to pass to handler” in the definition of <code>g_signal_connect</code> in <a href="https://docs.gtk.org/gobject/func.signal_connect.html">GObject API Reference</a>. Therefore, <code>win</code> which is a pointer to GtkApplicationWindow is passed to the handler as a second parameter <code>user_data</code>. The handler then casts it to a pointer to GtkWindow and calls <code>gtk_window_destroy</code> to destroy the top-level window. The application then quits.</p>
<h3 id="gtkbox">GtkBox</h3>
<p>GtkWindow and GtkApplicationWindow can have only one child. If you want to add two or more widgets in a window, you need a container widget. GtkBox is one of the containers. It arranges two or more child widgets into a single row or column. The following procedure shows the way to add two buttons in a window.</p>
<ul>
<li>Create a GtkApplicationWindow instance.</li>
<li>Create a GtkBox instance and add it to the GtkApplicationWindow as a child.</li>
<li>Create a GtkButton instance and append it to the GtkBox.</li>
<li>Create another GtkButton instance and append it to the GtkBox.</li>
</ul>
<p>After this, the Widgets are connected as the following diagram.</p>
<figure>
<img src="../image/box.png" alt="" /><figcaption>Parent-child relationship</figcaption>
</figure>
<p>The program <code>lb4.c</code> includes these widgets. It is as follows.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb7-1"><a href="#cb7-1"></a><span class="pp">#include </span><span class="im">&lt;gtk/gtk.h&gt;</span></span>
<span id="cb7-2"><a href="#cb7-2"></a></span>
<span id="cb7-3"><a href="#cb7-3"></a><span class="dt">static</span> <span class="dt">void</span></span>
<span id="cb7-4"><a href="#cb7-4"></a>click1_cb (GtkButton *btn, gpointer user_data) {</span>
<span id="cb7-5"><a href="#cb7-5"></a> <span class="dt">const</span> gchar *s;</span>
<span id="cb7-6"><a href="#cb7-6"></a></span>
<span id="cb7-7"><a href="#cb7-7"></a> s = gtk_button_get_label (btn);</span>
<span id="cb7-8"><a href="#cb7-8"></a> <span class="cf">if</span> (g_strcmp0 (s, <span class="st">&quot;Hello.&quot;</span>) == <span class="dv">0</span>)</span>
<span id="cb7-9"><a href="#cb7-9"></a> gtk_button_set_label (btn, <span class="st">&quot;Good-bye.&quot;</span>);</span>
<span id="cb7-10"><a href="#cb7-10"></a> <span class="cf">else</span></span>
<span id="cb7-11"><a href="#cb7-11"></a> gtk_button_set_label (btn, <span class="st">&quot;Hello.&quot;</span>);</span>
<span id="cb7-12"><a href="#cb7-12"></a>}</span>
<span id="cb7-13"><a href="#cb7-13"></a></span>
<span id="cb7-14"><a href="#cb7-14"></a><span class="dt">static</span> <span class="dt">void</span></span>
<span id="cb7-15"><a href="#cb7-15"></a>click2_cb (GtkButton *btn, gpointer user_data) {</span>
<span id="cb7-16"><a href="#cb7-16"></a> GtkWindow *win = GTK_WINDOW (user_data);</span>
<span id="cb7-17"><a href="#cb7-17"></a> gtk_window_destroy (win);</span>
<span id="cb7-18"><a href="#cb7-18"></a>}</span>
<span id="cb7-19"><a href="#cb7-19"></a></span>
<span id="cb7-20"><a href="#cb7-20"></a><span class="dt">static</span> <span class="dt">void</span></span>
<span id="cb7-21"><a href="#cb7-21"></a>app_activate (GApplication *app, gpointer user_data) {</span>
<span id="cb7-22"><a href="#cb7-22"></a> GtkWidget *win;</span>
<span id="cb7-23"><a href="#cb7-23"></a> GtkWidget *box;</span>
<span id="cb7-24"><a href="#cb7-24"></a> GtkWidget *btn1;</span>
<span id="cb7-25"><a href="#cb7-25"></a> GtkWidget *btn2;</span>
<span id="cb7-26"><a href="#cb7-26"></a></span>
<span id="cb7-27"><a href="#cb7-27"></a> win = gtk_application_window_new (GTK_APPLICATION (app));</span>
<span id="cb7-28"><a href="#cb7-28"></a> gtk_window_set_title (GTK_WINDOW (win), <span class="st">&quot;lb4&quot;</span>);</span>
<span id="cb7-29"><a href="#cb7-29"></a> gtk_window_set_default_size (GTK_WINDOW (win), <span class="dv">400</span>, <span class="dv">300</span>);</span>
<span id="cb7-30"><a href="#cb7-30"></a></span>
<span id="cb7-31"><a href="#cb7-31"></a> box = gtk_box_new (GTK_ORIENTATION_VERTICAL, <span class="dv">5</span>);</span>
<span id="cb7-32"><a href="#cb7-32"></a> gtk_box_set_homogeneous (GTK_BOX (box), TRUE);</span>
<span id="cb7-33"><a href="#cb7-33"></a> gtk_window_set_child (GTK_WINDOW (win), box);</span>
<span id="cb7-34"><a href="#cb7-34"></a></span>
<span id="cb7-35"><a href="#cb7-35"></a> btn1 = gtk_button_new_with_label (<span class="st">&quot;Hello.&quot;</span>);</span>
<span id="cb7-36"><a href="#cb7-36"></a> g_signal_connect (btn1, <span class="st">&quot;clicked&quot;</span>, G_CALLBACK (click1_cb), NULL);</span>
<span id="cb7-37"><a href="#cb7-37"></a></span>
<span id="cb7-38"><a href="#cb7-38"></a> btn2 = gtk_button_new_with_label (<span class="st">&quot;Quit&quot;</span>);</span>
<span id="cb7-39"><a href="#cb7-39"></a> g_signal_connect (btn2, <span class="st">&quot;clicked&quot;</span>, G_CALLBACK (click2_cb), win);</span>
<span id="cb7-40"><a href="#cb7-40"></a></span>
<span id="cb7-41"><a href="#cb7-41"></a> gtk_box_append (GTK_BOX (box), btn1);</span>
<span id="cb7-42"><a href="#cb7-42"></a> gtk_box_append (GTK_BOX (box), btn2);</span>
<span id="cb7-43"><a href="#cb7-43"></a></span>
<span id="cb7-44"><a href="#cb7-44"></a> gtk_widget_show (win);</span>
<span id="cb7-45"><a href="#cb7-45"></a>}</span>
<span id="cb7-46"><a href="#cb7-46"></a></span>
<span id="cb7-47"><a href="#cb7-47"></a><span class="dt">int</span></span>
<span id="cb7-48"><a href="#cb7-48"></a>main (<span class="dt">int</span> argc, <span class="dt">char</span> **argv) {</span>
<span id="cb7-49"><a href="#cb7-49"></a> GtkApplication *app;</span>
<span id="cb7-50"><a href="#cb7-50"></a> <span class="dt">int</span> stat;</span>
<span id="cb7-51"><a href="#cb7-51"></a></span>
<span id="cb7-52"><a href="#cb7-52"></a> app = gtk_application_new (<span class="st">&quot;com.github.ToshioCP.lb4&quot;</span>, G_APPLICATION_FLAGS_NONE);</span>
<span id="cb7-53"><a href="#cb7-53"></a> g_signal_connect (app, <span class="st">&quot;activate&quot;</span>, G_CALLBACK (app_activate), NULL);</span>
<span id="cb7-54"><a href="#cb7-54"></a> stat =g_application_run (G_APPLICATION (app), argc, argv);</span>
<span id="cb7-55"><a href="#cb7-55"></a> g_object_unref (app);</span>
<span id="cb7-56"><a href="#cb7-56"></a> <span class="cf">return</span> stat;</span>
<span id="cb7-57"><a href="#cb7-57"></a>}</span></code></pre></div>
<p>Look at the function <code>app_activate</code>.</p>
<p>After the creation of a GtkApplicationWindow instance, a GtkBox instance is created.</p>
<pre><code>box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);</code></pre>
<p>The first argument arranges the children of the box vertically. The second argument is the size between the children. The next function fills the box with the children, giving them the same space.</p>
<p>After that, two buttons <code>btn1</code> and <code>btn2</code> are created and the signal handlers are set. Then, these two buttons are appended to the box.</p>
<figure>
<img src="../image/screenshot_lb4.png" alt="" /><figcaption>Screenshot of the box</figcaption>
</figure>
<p>The handler corresponds to <code>btn1</code> toggles its label. The handler corresponds to <code>btn2</code> destroys the top-level window and the application quits.</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>