2021-01-13 05:29:35 +01:00
|
|
|
# Widgets (1)
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
## GtkLabel, GtkButton and Gtkbox
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
### GtkLabel
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-26 14:36:17 +01:00
|
|
|
We made a window and show it on the screen in the previous section.
|
2021-01-13 05:29:35 +01:00
|
|
|
Now we go on to the next topic, widgets in the window.
|
|
|
|
The simplest widget is GtkLabel.
|
|
|
|
It is a widget with a string in it.
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
@@@ misc/lb1.c
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
Save this program to a file `lb1.c`.
|
|
|
|
Then compile and run it.
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
$ comp lb1
|
|
|
|
$ ./a.out
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
A window with a message "Hello." appears.
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
![Screenshot of the label](../image/screenshot_lb1.png){width=6.3cm height=5.325cm}
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
There's only a little change between `pr4.c` and `lb1.c`.
|
|
|
|
Diff is a good program to know the difference between two files.
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
$$$
|
|
|
|
cd misc; diff pr4.c lb1.c
|
|
|
|
$$$
|
|
|
|
|
|
|
|
This tells us:
|
|
|
|
|
|
|
|
- The definition of a variable lab is added.
|
|
|
|
- The title of the window is changed.
|
|
|
|
- A label is generated and connected to the window.
|
|
|
|
|
|
|
|
The function `gtk_window_set_child (GTK_WINDOW (win), lab)` makes the label `lab` a child widget of the window `win`.
|
|
|
|
Be careful.
|
|
|
|
A child widget is different from a child object.
|
|
|
|
Objects have parent-child relationship and Widgets also have parent-child relationship.
|
|
|
|
But these two relationships are totally different.
|
|
|
|
Don't be confused.
|
|
|
|
In the program `lb1.c`, `lab` is a child widget of `win`.
|
|
|
|
Child widgets are always located inside its parent widget in the screen.
|
|
|
|
See the window appeared on the screen.
|
|
|
|
The window includes the label.
|
|
|
|
|
2021-01-26 14:36:17 +01:00
|
|
|
The window `win` doesn't have any parents.
|
2021-01-13 05:29:35 +01:00
|
|
|
We call such a window top-level window.
|
|
|
|
One application can have two or more top-level windows.
|
|
|
|
|
|
|
|
### GtkButton
|
|
|
|
|
|
|
|
Next widget is GtkButton.
|
|
|
|
It has a label or icon on it.
|
|
|
|
In this subsection, we will make a button with a label.
|
|
|
|
When a button is clicked on, it emits a "clicked" signal.
|
|
|
|
The following program shows how to catch the signal and do something.
|
|
|
|
|
|
|
|
@@@ misc/lb2.c
|
|
|
|
|
|
|
|
Look at the line 17 to 19.
|
2021-02-06 09:26:57 +01:00
|
|
|
First, it generates a GtkButton widget `btn` with a label "Click me".
|
|
|
|
Then, adds the button to the window `win` as a child.
|
|
|
|
Finally, connects a "clicked" signal of the button to a handler (function) `click_cb`.
|
2021-01-13 05:29:35 +01:00
|
|
|
So, if `btn` is clicked, the function `click_cb` is invoked.
|
|
|
|
The suffix cb means "call back".
|
|
|
|
|
|
|
|
Name the program `lb2.c` and save it.
|
|
|
|
Now compile and run it.
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
![Screenshot of the label](../image/screenshot_lb2.png){width=11.205cm height=6.945cm}
|
|
|
|
|
|
|
|
A window with the button appears.
|
|
|
|
Click the button (it is a large button, you can click everywhere inside the window), then a string "Clicked." appears on the shell terminal.
|
|
|
|
It shows the handler was invoked by clicking the button.
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
It's fairly good for us to make sure that the clicked signal was caught and the handler was invoked.
|
|
|
|
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 `lb3.c`.
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
@@@ misc/lb3.c click_cb on_activate
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
And the difference between `lb2.c` and `lb3.c` is as follows.
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2020-12-22 03:30:06 +01:00
|
|
|
$$$
|
2021-01-13 05:29:35 +01:00
|
|
|
cd misc; diff lb2.c lb3.c
|
2020-12-22 03:30:06 +01:00
|
|
|
$$$
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
The change is:
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
- The function `g_print` in `lb2.c` was deleted and two lines above are inserted instead.
|
|
|
|
- The label of `btn` is changed from "Click me" to "Quit".
|
|
|
|
- The fourth argument of `g_signal_connect` is changed from `NULL` to `win`.
|
2020-12-21 13:12:05 +01:00
|
|
|
|
2021-01-13 05:29:35 +01:00
|
|
|
Most important is the fourth argument of `g_signal_connect`.
|
|
|
|
It is described as "data to pass to handler" in the definition of g\_signal\_connect in GObject API reference.
|
|
|
|
Therefore, `win` which is a pointer to GtkApplicationWindow is passed to the handler as a second parameter user_data.
|
|
|
|
Then, the handler cast it to a pointer to GtkWindow and call `gtk_window_destroy` and destroy the top window.
|
|
|
|
Then, the application quits.
|
|
|
|
|
|
|
|
### GtkBox
|
|
|
|
|
|
|
|
GtkWindow and GtkApplicationWindow can have only one child.
|
|
|
|
If you want to add two or more widgets inside 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.
|
|
|
|
|
|
|
|
- Generate GtkApplicationWindow.
|
2021-02-06 09:26:57 +01:00
|
|
|
- Generate GtkBox and add it to GtkApplicationWindow as a child.
|
2021-01-13 05:29:35 +01:00
|
|
|
- Generate GtkButton and append it to GtkBox.
|
|
|
|
- Generate another GtkButton and append it to GtkBox.
|
|
|
|
|
|
|
|
After this, the Widgets are connected as following diagram.
|
|
|
|
|
|
|
|
![Parent-child relationship](../image/box.png){width=7.725cm height=2.055cm}
|
|
|
|
|
|
|
|
Now, code it.
|
|
|
|
|
|
|
|
@@@ misc/lb4.c
|
|
|
|
|
|
|
|
Look at the function `on_activate`.
|
|
|
|
|
|
|
|
After the generation of GtkApplicationWindow, GtkBox is generated.
|
|
|
|
|
|
|
|
box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
|
|
|
|
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
|
|
|
|
|
|
|
|
The first argument arranges children vertically.
|
|
|
|
The second argument is the size between children.
|
|
|
|
The next function fills a box with children, giving them equal space.
|
|
|
|
|
|
|
|
After that, two buttons `btn1` and `btn2` are generated and the signal handlers are set.
|
|
|
|
Then, these two buttons are appended to the box.
|
|
|
|
|
|
|
|
![Screenshot of the box](../image/screenshot_lb4.png){width=6.3cm height=5.325cm}
|
|
|
|
|
|
|
|
The handler corresponds to `btn1` changes its label.
|
|
|
|
The handler corresponds to `btn2` destroys the top-level window and the application quits.
|
2020-12-21 13:12:05 +01:00
|
|
|
|