mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2025-01-29 20:34:16 +01:00
modified section two to three.
This commit is contained in:
parent
49055b1cb6
commit
2788a3712b
12 changed files with 79 additions and 72 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,6 +5,7 @@ makehtml.rb
|
||||||
pickoutfunc.rb
|
pickoutfunc.rb
|
||||||
src/img.rb
|
src/img.rb
|
||||||
src/toi.rb
|
src/toi.rb
|
||||||
|
src/misc/a.out
|
||||||
|
|
||||||
# backup file
|
# backup file
|
||||||
*~
|
*~
|
||||||
|
|
|
@ -33,7 +33,7 @@ def src2md srcmd, md
|
||||||
c_functions.each do |c_function|
|
c_functions.each do |c_function|
|
||||||
from = c_file_buf.find_index { |line| line =~ /^#{c_function} *\(/ }
|
from = c_file_buf.find_index { |line| line =~ /^#{c_function} *\(/ }
|
||||||
if ! from
|
if ! from
|
||||||
warn "ERROR!!! --- Didn't find #{func} in #{filename}. ---"
|
warn "ERROR!!! --- Didn't find #{c_function} in #{filename}. ---"
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
to = from
|
to = from
|
||||||
|
|
2
sec14.md
2
sec14.md
|
@ -616,5 +616,5 @@ The followings are the source files of tfe5.
|
||||||
218 622 7454 tfe5/tfetextview.c
|
218 622 7454 tfe5/tfetextview.c
|
||||||
29 47 545 tfe5/tfetextview.h
|
29 47 545 tfe5/tfetextview.h
|
||||||
64 105 2266 tfe5/tfe.ui
|
64 105 2266 tfe5/tfe.ui
|
||||||
574 1482 17411 合計
|
574 1482 17411 total
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 13](sec13.md), Next: [Section 15](sec15.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 13](sec13.md), Next: [Section 15](sec15.md)
|
||||||
|
|
26
sec2.md
26
sec2.md
|
@ -33,18 +33,18 @@ The following is the C code representing the scenario above.
|
||||||
12 }
|
12 }
|
||||||
13
|
13
|
||||||
|
|
||||||
The first line says that this program includes the GTK header libraries.
|
The first line says that this program includes the header files of the Gtk libraries.
|
||||||
The function `main` above is a startup function in C language.
|
The function `main` above is a startup function in C language.
|
||||||
The variable `app` is defined as a pointer to GtkApplication, which is actually a structure in which information about the application is stored.
|
The variable `app` is defined as a pointer to GtkApplication, which is actually a structure in which information about the application is stored.
|
||||||
The function `gtk_application_new` generates a GtkApplication and sets its pointer to `app`.
|
The function `gtk_application_new` generates a GtkApplication object and sets its pointer to `app`.
|
||||||
The meaning of the arguments will be explained later.
|
The meaning of the arguments will be explained later.
|
||||||
The function `g_application_run` invokes the GtkApplication pointed by `app`.
|
The function `g_application_run` invokes the GtkApplication object pointed by `app`.
|
||||||
(We often say that the function invokes `app`.
|
(We often say that the function invokes `app`.
|
||||||
Actually, `app` is not an object but an pointer to the object.
|
Actually, `app` is not an object but an pointer to the object.
|
||||||
However, it is simple and short, and probably no confusion occurs.)
|
However, it is simple and short, and probably no confusion occurs.)
|
||||||
|
|
||||||
To compile this, the following command needs to be run.
|
To compile this, the following command needs to be run.
|
||||||
The string pr1.c is the filename of the C source code.
|
The string pr1.c is the filename of the C source code above.
|
||||||
|
|
||||||
$ gcc `pkg-config --cflags gtk4` pr1.c `pkg-config --libs gtk4`
|
$ gcc `pkg-config --cflags gtk4` pr1.c `pkg-config --libs gtk4`
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ Let's run it.
|
||||||
|
|
||||||
Oh, just an error message.
|
Oh, just an error message.
|
||||||
But this error message means that the GtkApplication object ran without a doubt.
|
But this error message means that the GtkApplication object ran without a doubt.
|
||||||
Now, think about the message in the next section.
|
Now, think about the message in the next subsection.
|
||||||
|
|
||||||
### signal
|
### signal
|
||||||
|
|
||||||
|
@ -66,9 +66,9 @@ The message tells us that:
|
||||||
|
|
||||||
1. The application GtkApplication doesn't implement `g_application_activate()`.
|
1. The application GtkApplication doesn't implement `g_application_activate()`.
|
||||||
2. And it has no handlers connected to the activate signal.
|
2. And it has no handlers connected to the activate signal.
|
||||||
3. You need to solve at least one of this.
|
3. You need to solve at least one of these.
|
||||||
|
|
||||||
These two cause of the error are related to signals.
|
These two causes of the error are related to signals.
|
||||||
So, I will explain it to you first.
|
So, I will explain it to you first.
|
||||||
|
|
||||||
Signal is emitted when something happens.
|
Signal is emitted when something happens.
|
||||||
|
@ -132,8 +132,9 @@ The handler function is described in that subsection.
|
||||||
In addition, `g_signal_connect` is described in GObject API reference.
|
In addition, `g_signal_connect` is described in GObject API reference.
|
||||||
API reference is very important.
|
API reference is very important.
|
||||||
You should see and understand it to write GTK applications.
|
You should see and understand it to write GTK applications.
|
||||||
|
They are located in ['GNOME Developer Center'](https://developer.gnome.org/).
|
||||||
|
|
||||||
Let's compile the source file `pr2.c` above and run it.
|
Let's compile the source file above (`pr2.c`) and run it.
|
||||||
|
|
||||||
$ gcc `pkg-config --cflags gtk4` pr2.c `pkg-config --libs gtk4`
|
$ gcc `pkg-config --cflags gtk4` pr2.c `pkg-config --libs gtk4`
|
||||||
$ ./a.out
|
$ ./a.out
|
||||||
|
@ -143,14 +144,14 @@ Let's compile the source file `pr2.c` above and run it.
|
||||||
OK, well done.
|
OK, well done.
|
||||||
However, you may have noticed that it's painful to type such a long line to compile.
|
However, you may have noticed that it's painful to type such a long line to compile.
|
||||||
It is a good idea to use shell script to solve this problem.
|
It is a good idea to use shell script to solve this problem.
|
||||||
Make a text file which contains the following text.
|
Make a text file which contains the following line.
|
||||||
|
|
||||||
gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`
|
gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`
|
||||||
|
|
||||||
Then, save it in $HOME/bin, which is usually /home/(username)/bin.
|
Then, save it under the directory $HOME/bin, which is usually /home/(username)/bin.
|
||||||
(If your user name is James, then the directory is /home/james/bin).
|
(If your user name is James, then the directory is /home/james/bin).
|
||||||
And turn on the execute bit of the file.
|
And turn on the execute bit of the file.
|
||||||
Suppose the filename is comp, then the procedure is as follows.
|
Suppose the filename is `comp`, then the procedure is as follows.
|
||||||
|
|
||||||
$ chmod 755 $HOME/bin/comp
|
$ chmod 755 $HOME/bin/comp
|
||||||
$ ls -log $HOME/bin
|
$ ls -log $HOME/bin
|
||||||
|
@ -231,7 +232,7 @@ You need to cast `win` to GtkWindow and `app` to GtkApplication.
|
||||||
`GTK_WINDOW` and `GTK_APPLICATION` macro is appropriate for that.
|
`GTK_WINDOW` and `GTK_APPLICATION` macro is appropriate for that.
|
||||||
|
|
||||||
GtkApplication continues to run until the related window is destroyed.
|
GtkApplication continues to run until the related window is destroyed.
|
||||||
If you didn't connect GtkWindow and GtkApplication, GtkApplication shutdowns soon.
|
If you didn't connect GtkWindow and GtkApplication, GtkApplication shutdowns immediately.
|
||||||
Because no window is connected to GtkApplication, it doesn't need to wait anything.
|
Because no window is connected to GtkApplication, it doesn't need to wait anything.
|
||||||
As it shutdowns the generated window is also destroyed.
|
As it shutdowns the generated window is also destroyed.
|
||||||
|
|
||||||
|
@ -281,5 +282,4 @@ The program sets the title and the default size of the window.
|
||||||
Compile it and run `a.out`, then you will see a bigger window with its title "pr4".
|
Compile it and run `a.out`, then you will see a bigger window with its title "pr4".
|
||||||
|
|
||||||
![Screenshot of the window](image/screenshot_pr4.png)
|
![Screenshot of the window](image/screenshot_pr4.png)
|
||||||
|
|
||||||
Up: [Readme.md](Readme.md), Prev: [Section 1](sec1.md), Next: [Section 3](sec3.md)
|
Up: [Readme.md](Readme.md), Prev: [Section 1](sec1.md), Next: [Section 3](sec3.md)
|
||||||
|
|
48
sec3.md
48
sec3.md
|
@ -5,7 +5,7 @@ Up: [Readme.md](Readme.md), Prev: [Section 2](sec2.md), Next: [Section 4](sec4.
|
||||||
|
|
||||||
### GtkLabel
|
### GtkLabel
|
||||||
|
|
||||||
We made an window and show it on the screen in the previous chapter.
|
We made an window and show it on the screen in the previous section.
|
||||||
Now we go on to the next topic, widgets in the window.
|
Now we go on to the next topic, widgets in the window.
|
||||||
The simplest widget is GtkLabel.
|
The simplest widget is GtkLabel.
|
||||||
It is a widget with a string in it.
|
It is a widget with a string in it.
|
||||||
|
@ -18,7 +18,7 @@ It is a widget with a string in it.
|
||||||
6 GtkWidget *lab;
|
6 GtkWidget *lab;
|
||||||
7
|
7
|
||||||
8 win = gtk_application_window_new (GTK_APPLICATION (app));
|
8 win = gtk_application_window_new (GTK_APPLICATION (app));
|
||||||
9 gtk_window_set_title (GTK_WINDOW (win), "lb4");
|
9 gtk_window_set_title (GTK_WINDOW (win), "lb1");
|
||||||
10 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
10 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
||||||
11
|
11
|
||||||
12 lab = gtk_label_new ("Hello.");
|
12 lab = gtk_label_new ("Hello.");
|
||||||
|
@ -53,13 +53,13 @@ A window with a message "Hello." appears.
|
||||||
There's only a little change between `pr4.c` and `lb1.c`.
|
There's only a little change between `pr4.c` and `lb1.c`.
|
||||||
Diff is a good program to know the difference between two files.
|
Diff is a good program to know the difference between two files.
|
||||||
|
|
||||||
$ diff misc/pr4.c lb1.c
|
$ cd misc; diff pr4.c lb1.c
|
||||||
5a6
|
5a6
|
||||||
> GtkWidget *lab;
|
> GtkWidget *lab;
|
||||||
8c9
|
8c9
|
||||||
< gtk_window_set_title (GTK_WINDOW (win), "pr4");
|
< gtk_window_set_title (GTK_WINDOW (win), "pr4");
|
||||||
---
|
---
|
||||||
> gtk_window_set_title (GTK_WINDOW (win), "lb4");
|
> gtk_window_set_title (GTK_WINDOW (win), "lb1");
|
||||||
9a11,14
|
9a11,14
|
||||||
>
|
>
|
||||||
> lab = gtk_label_new ("Hello.");
|
> lab = gtk_label_new ("Hello.");
|
||||||
|
@ -102,7 +102,7 @@ The following program shows how to catch the signal and do something.
|
||||||
1 #include <gtk/gtk.h>
|
1 #include <gtk/gtk.h>
|
||||||
2
|
2
|
||||||
3 static void
|
3 static void
|
||||||
4 on_clicked (GtkButton *btn, gpointer user_data) {
|
4 click_cb (GtkButton *btn, gpointer user_data) {
|
||||||
5 g_print ("Clicked.\n");
|
5 g_print ("Clicked.\n");
|
||||||
6 }
|
6 }
|
||||||
7
|
7
|
||||||
|
@ -112,12 +112,12 @@ The following program shows how to catch the signal and do something.
|
||||||
11 GtkWidget *btn;
|
11 GtkWidget *btn;
|
||||||
12
|
12
|
||||||
13 win = gtk_application_window_new (GTK_APPLICATION (app));
|
13 win = gtk_application_window_new (GTK_APPLICATION (app));
|
||||||
14 gtk_window_set_title (GTK_WINDOW (win), "lb4");
|
14 gtk_window_set_title (GTK_WINDOW (win), "lb2");
|
||||||
15 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
15 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
||||||
16
|
16
|
||||||
17 btn = gtk_button_new_with_label ("Click me");
|
17 btn = gtk_button_new_with_label ("Click me");
|
||||||
18 gtk_window_set_child (GTK_WINDOW (win), btn);
|
18 gtk_window_set_child (GTK_WINDOW (win), btn);
|
||||||
19 g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), NULL);
|
19 g_signal_connect (btn, "clicked", G_CALLBACK (click_cb), NULL);
|
||||||
20
|
20
|
||||||
21 gtk_widget_show (win);
|
21 gtk_widget_show (win);
|
||||||
22 }
|
22 }
|
||||||
|
@ -138,8 +138,9 @@ The following program shows how to catch the signal and do something.
|
||||||
Look at the line 17 to 19.
|
Look at the line 17 to 19.
|
||||||
First, generate a GtkButton widget `btn` with a label "Click me".
|
First, generate a GtkButton widget `btn` with a label "Click me".
|
||||||
Then, set it to the window `win` as a child.
|
Then, set it to the window `win` as a child.
|
||||||
Finally, connect a "clicked" signal of the button to a handler (function) `on_click`.
|
Finally, connect a "clicked" signal of the button to a handler (function) `click_cb`.
|
||||||
So, if `btn` is clicked, the function `on_click` is invoked.
|
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.
|
Name the program `lb2.c` and save it.
|
||||||
Now compile and run it.
|
Now compile and run it.
|
||||||
|
@ -156,7 +157,7 @@ So, we will change the handler.
|
||||||
The following code is `lb3.c`.
|
The following code is `lb3.c`.
|
||||||
|
|
||||||
1 static void
|
1 static void
|
||||||
2 on_clicked (GtkButton *btn, gpointer user_data) {
|
2 click_cb (GtkButton *btn, gpointer user_data) {
|
||||||
3 GtkWindow *win = GTK_WINDOW (user_data);
|
3 GtkWindow *win = GTK_WINDOW (user_data);
|
||||||
4 gtk_window_destroy (win);
|
4 gtk_window_destroy (win);
|
||||||
5 }
|
5 }
|
||||||
|
@ -167,36 +168,42 @@ The following code is `lb3.c`.
|
||||||
10 GtkWidget *btn;
|
10 GtkWidget *btn;
|
||||||
11
|
11
|
||||||
12 win = gtk_application_window_new (GTK_APPLICATION (app));
|
12 win = gtk_application_window_new (GTK_APPLICATION (app));
|
||||||
13 gtk_window_set_title (GTK_WINDOW (win), "lb4");
|
13 gtk_window_set_title (GTK_WINDOW (win), "lb3");
|
||||||
14 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
14 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
||||||
15
|
15
|
||||||
16 btn = gtk_button_new_with_label ("Quit");
|
16 btn = gtk_button_new_with_label ("Quit");
|
||||||
17 gtk_window_set_child (GTK_WINDOW (win), btn);
|
17 gtk_window_set_child (GTK_WINDOW (win), btn);
|
||||||
18 g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), win);
|
18 g_signal_connect (btn, "clicked", G_CALLBACK (click_cb), win);
|
||||||
19
|
19
|
||||||
20 gtk_widget_show (win);
|
20 gtk_widget_show (win);
|
||||||
21 }
|
21 }
|
||||||
|
|
||||||
And the difference between `lb2.c` and `lb3.c` is as follows.
|
And the difference between `lb2.c` and `lb3.c` is as follows.
|
||||||
|
|
||||||
$ diff lb2.c lb3.c
|
$ cd misc; diff lb2.c lb3.c
|
||||||
5c5,6
|
5c5,6
|
||||||
< g_print ("Clicked.\n");
|
< g_print ("Clicked.\n");
|
||||||
---
|
---
|
||||||
> GtkWindow *win = GTK_WINDOW (user_data);
|
> GtkWindow *win = GTK_WINDOW (user_data);
|
||||||
> gtk_window_destroy (win);
|
> gtk_window_destroy (win);
|
||||||
|
14c15
|
||||||
|
< gtk_window_set_title (GTK_WINDOW (win), "lb2");
|
||||||
|
---
|
||||||
|
> gtk_window_set_title (GTK_WINDOW (win), "lb3");
|
||||||
17c18
|
17c18
|
||||||
< btn = gtk_button_new_with_label ("Click me");
|
< btn = gtk_button_new_with_label ("Click me");
|
||||||
---
|
---
|
||||||
> btn = gtk_button_new_with_label ("Quit");
|
> btn = gtk_button_new_with_label ("Quit");
|
||||||
19c20
|
19c20
|
||||||
< g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), NULL);
|
< g_signal_connect (btn, "clicked", G_CALLBACK (click_cb), NULL);
|
||||||
---
|
---
|
||||||
> g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), win);
|
> g_signal_connect (btn, "clicked", G_CALLBACK (click_cb), win);
|
||||||
29c30
|
29c30
|
||||||
< app = gtk_application_new ("com.github.ToshioCP.lb2", G_APPLICATION_FLAGS_NONE);
|
< app = gtk_application_new ("com.github.ToshioCP.lb2", G_APPLICATION_FLAGS_NONE);
|
||||||
---
|
---
|
||||||
> app = gtk_application_new ("com.github.ToshioCP.lb3", G_APPLICATION_FLAGS_NONE);
|
> app = gtk_application_new ("com.github.ToshioCP.lb3", G_APPLICATION_FLAGS_NONE);
|
||||||
|
35d35
|
||||||
|
<
|
||||||
|
|
||||||
The change is:
|
The change is:
|
||||||
|
|
||||||
|
@ -232,7 +239,7 @@ Now, code it.
|
||||||
1 #include <gtk/gtk.h>
|
1 #include <gtk/gtk.h>
|
||||||
2
|
2
|
||||||
3 static void
|
3 static void
|
||||||
4 on_clicked1 (GtkButton *btn, gpointer user_data) {
|
4 click1_cb (GtkButton *btn, gpointer user_data) {
|
||||||
5 const gchar *s;
|
5 const gchar *s;
|
||||||
6
|
6
|
||||||
7 s = gtk_button_get_label (btn);
|
7 s = gtk_button_get_label (btn);
|
||||||
|
@ -243,7 +250,7 @@ Now, code it.
|
||||||
12 }
|
12 }
|
||||||
13
|
13
|
||||||
14 static void
|
14 static void
|
||||||
15 on_clicked2 (GtkButton *btn, gpointer user_data) {
|
15 click2_cb (GtkButton *btn, gpointer user_data) {
|
||||||
16 GtkWindow *win = GTK_WINDOW (user_data);
|
16 GtkWindow *win = GTK_WINDOW (user_data);
|
||||||
17 gtk_window_destroy (win);
|
17 gtk_window_destroy (win);
|
||||||
18 }
|
18 }
|
||||||
|
@ -264,10 +271,10 @@ Now, code it.
|
||||||
33 gtk_window_set_child (GTK_WINDOW (win), box);
|
33 gtk_window_set_child (GTK_WINDOW (win), box);
|
||||||
34
|
34
|
||||||
35 btn1 = gtk_button_new_with_label ("Hello.");
|
35 btn1 = gtk_button_new_with_label ("Hello.");
|
||||||
36 g_signal_connect (btn1, "clicked", G_CALLBACK (on_clicked1), NULL);
|
36 g_signal_connect (btn1, "clicked", G_CALLBACK (click1_cb), NULL);
|
||||||
37
|
37
|
||||||
38 btn2 = gtk_button_new_with_label ("Quit");
|
38 btn2 = gtk_button_new_with_label ("Quit");
|
||||||
39 g_signal_connect (btn2, "clicked", G_CALLBACK (on_clicked2), win);
|
39 g_signal_connect (btn2, "clicked", G_CALLBACK (click2_cb), win);
|
||||||
40
|
40
|
||||||
41 gtk_box_append (GTK_BOX (box), btn1);
|
41 gtk_box_append (GTK_BOX (box), btn1);
|
||||||
42 gtk_box_append (GTK_BOX (box), btn2);
|
42 gtk_box_append (GTK_BOX (box), btn2);
|
||||||
|
@ -286,7 +293,6 @@ Now, code it.
|
||||||
55 g_object_unref (app);
|
55 g_object_unref (app);
|
||||||
56 return stat;
|
56 return stat;
|
||||||
57 }
|
57 }
|
||||||
58
|
|
||||||
|
|
||||||
Look at the function `on_activate`.
|
Look at the function `on_activate`.
|
||||||
|
|
||||||
|
@ -296,7 +302,7 @@ After the generation of GtkApplicationWindow, GtkBox is generated.
|
||||||
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
|
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
|
||||||
|
|
||||||
The first argument arranges children vertically.
|
The first argument arranges children vertically.
|
||||||
The second argument is sizes between children.
|
The second argument is the size between children.
|
||||||
The next function fills a box with children, giving them equal space.
|
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.
|
After that, two buttons `btn1` and `btn2` are generated and the signal handlers are set.
|
||||||
|
|
1
src/misc/comp
Executable file
1
src/misc/comp
Executable file
|
@ -0,0 +1 @@
|
||||||
|
gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`
|
|
@ -6,7 +6,7 @@ on_activate (GApplication *app, gpointer user_data) {
|
||||||
GtkWidget *lab;
|
GtkWidget *lab;
|
||||||
|
|
||||||
win = gtk_application_window_new (GTK_APPLICATION (app));
|
win = gtk_application_window_new (GTK_APPLICATION (app));
|
||||||
gtk_window_set_title (GTK_WINDOW (win), "lb4");
|
gtk_window_set_title (GTK_WINDOW (win), "lb1");
|
||||||
gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
||||||
|
|
||||||
lab = gtk_label_new ("Hello.");
|
lab = gtk_label_new ("Hello.");
|
|
@ -1,7 +1,7 @@
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_clicked (GtkButton *btn, gpointer user_data) {
|
click_cb (GtkButton *btn, gpointer user_data) {
|
||||||
g_print ("Clicked.\n");
|
g_print ("Clicked.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,12 +11,12 @@ on_activate (GApplication *app, gpointer user_data) {
|
||||||
GtkWidget *btn;
|
GtkWidget *btn;
|
||||||
|
|
||||||
win = gtk_application_window_new (GTK_APPLICATION (app));
|
win = gtk_application_window_new (GTK_APPLICATION (app));
|
||||||
gtk_window_set_title (GTK_WINDOW (win), "lb4");
|
gtk_window_set_title (GTK_WINDOW (win), "lb2");
|
||||||
gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
||||||
|
|
||||||
btn = gtk_button_new_with_label ("Click me");
|
btn = gtk_button_new_with_label ("Click me");
|
||||||
gtk_window_set_child (GTK_WINDOW (win), btn);
|
gtk_window_set_child (GTK_WINDOW (win), btn);
|
||||||
g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), NULL);
|
g_signal_connect (btn, "clicked", G_CALLBACK (click_cb), NULL);
|
||||||
|
|
||||||
gtk_widget_show (win);
|
gtk_widget_show (win);
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_clicked (GtkButton *btn, gpointer user_data) {
|
click_cb (GtkButton *btn, gpointer user_data) {
|
||||||
GtkWindow *win = GTK_WINDOW (user_data);
|
GtkWindow *win = GTK_WINDOW (user_data);
|
||||||
gtk_window_destroy (win);
|
gtk_window_destroy (win);
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,12 @@ on_activate (GApplication *app, gpointer user_data) {
|
||||||
GtkWidget *btn;
|
GtkWidget *btn;
|
||||||
|
|
||||||
win = gtk_application_window_new (GTK_APPLICATION (app));
|
win = gtk_application_window_new (GTK_APPLICATION (app));
|
||||||
gtk_window_set_title (GTK_WINDOW (win), "lb4");
|
gtk_window_set_title (GTK_WINDOW (win), "lb3");
|
||||||
gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
|
||||||
|
|
||||||
btn = gtk_button_new_with_label ("Quit");
|
btn = gtk_button_new_with_label ("Quit");
|
||||||
gtk_window_set_child (GTK_WINDOW (win), btn);
|
gtk_window_set_child (GTK_WINDOW (win), btn);
|
||||||
g_signal_connect (btn, "clicked", G_CALLBACK (on_clicked), win);
|
g_signal_connect (btn, "clicked", G_CALLBACK (click_cb), win);
|
||||||
|
|
||||||
gtk_widget_show (win);
|
gtk_widget_show (win);
|
||||||
}
|
}
|
||||||
|
@ -33,4 +33,3 @@ main (int argc, char **argv) {
|
||||||
g_object_unref (app);
|
g_object_unref (app);
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_clicked1 (GtkButton *btn, gpointer user_data) {
|
click1_cb (GtkButton *btn, gpointer user_data) {
|
||||||
const gchar *s;
|
const gchar *s;
|
||||||
|
|
||||||
s = gtk_button_get_label (btn);
|
s = gtk_button_get_label (btn);
|
||||||
|
@ -12,7 +12,7 @@ on_clicked1 (GtkButton *btn, gpointer user_data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_clicked2 (GtkButton *btn, gpointer user_data) {
|
click2_cb (GtkButton *btn, gpointer user_data) {
|
||||||
GtkWindow *win = GTK_WINDOW (user_data);
|
GtkWindow *win = GTK_WINDOW (user_data);
|
||||||
gtk_window_destroy (win);
|
gtk_window_destroy (win);
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,10 @@ on_activate (GApplication *app, gpointer user_data) {
|
||||||
gtk_window_set_child (GTK_WINDOW (win), box);
|
gtk_window_set_child (GTK_WINDOW (win), box);
|
||||||
|
|
||||||
btn1 = gtk_button_new_with_label ("Hello.");
|
btn1 = gtk_button_new_with_label ("Hello.");
|
||||||
g_signal_connect (btn1, "clicked", G_CALLBACK (on_clicked1), NULL);
|
g_signal_connect (btn1, "clicked", G_CALLBACK (click1_cb), NULL);
|
||||||
|
|
||||||
btn2 = gtk_button_new_with_label ("Quit");
|
btn2 = gtk_button_new_with_label ("Quit");
|
||||||
g_signal_connect (btn2, "clicked", G_CALLBACK (on_clicked2), win);
|
g_signal_connect (btn2, "clicked", G_CALLBACK (click2_cb), win);
|
||||||
|
|
||||||
gtk_box_append (GTK_BOX (box), btn1);
|
gtk_box_append (GTK_BOX (box), btn1);
|
||||||
gtk_box_append (GTK_BOX (box), btn2);
|
gtk_box_append (GTK_BOX (box), btn2);
|
||||||
|
@ -55,4 +55,3 @@ main (int argc, char **argv) {
|
||||||
g_object_unref (app);
|
g_object_unref (app);
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,18 +20,18 @@ The following is the C code representing the scenario above.
|
||||||
|
|
||||||
@@@ misc/pr1.c
|
@@@ misc/pr1.c
|
||||||
|
|
||||||
The first line says that this program includes the GTK header libraries.
|
The first line says that this program includes the header files of the Gtk libraries.
|
||||||
The function `main` above is a startup function in C language.
|
The function `main` above is a startup function in C language.
|
||||||
The variable `app` is defined as a pointer to GtkApplication, which is actually a structure in which information about the application is stored.
|
The variable `app` is defined as a pointer to GtkApplication, which is actually a structure in which information about the application is stored.
|
||||||
The function `gtk_application_new` generates a GtkApplication and sets its pointer to `app`.
|
The function `gtk_application_new` generates a GtkApplication object and sets its pointer to `app`.
|
||||||
The meaning of the arguments will be explained later.
|
The meaning of the arguments will be explained later.
|
||||||
The function `g_application_run` invokes the GtkApplication pointed by `app`.
|
The function `g_application_run` invokes the GtkApplication object pointed by `app`.
|
||||||
(We often say that the function invokes `app`.
|
(We often say that the function invokes `app`.
|
||||||
Actually, `app` is not an object but an pointer to the object.
|
Actually, `app` is not an object but an pointer to the object.
|
||||||
However, it is simple and short, and probably no confusion occurs.)
|
However, it is simple and short, and probably no confusion occurs.)
|
||||||
|
|
||||||
To compile this, the following command needs to be run.
|
To compile this, the following command needs to be run.
|
||||||
The string pr1.c is the filename of the C source code.
|
The string pr1.c is the filename of the C source code above.
|
||||||
|
|
||||||
$ gcc `pkg-config --cflags gtk4` pr1.c `pkg-config --libs gtk4`
|
$ gcc `pkg-config --cflags gtk4` pr1.c `pkg-config --libs gtk4`
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ Let's run it.
|
||||||
|
|
||||||
Oh, just an error message.
|
Oh, just an error message.
|
||||||
But this error message means that the GtkApplication object ran without a doubt.
|
But this error message means that the GtkApplication object ran without a doubt.
|
||||||
Now, think about the message in the next section.
|
Now, think about the message in the next subsection.
|
||||||
|
|
||||||
### signal
|
### signal
|
||||||
|
|
||||||
|
@ -53,9 +53,9 @@ The message tells us that:
|
||||||
|
|
||||||
1. The application GtkApplication doesn't implement `g_application_activate()`.
|
1. The application GtkApplication doesn't implement `g_application_activate()`.
|
||||||
2. And it has no handlers connected to the activate signal.
|
2. And it has no handlers connected to the activate signal.
|
||||||
3. You need to solve at least one of this.
|
3. You need to solve at least one of these.
|
||||||
|
|
||||||
These two cause of the error are related to signals.
|
These two causes of the error are related to signals.
|
||||||
So, I will explain it to you first.
|
So, I will explain it to you first.
|
||||||
|
|
||||||
Signal is emitted when something happens.
|
Signal is emitted when something happens.
|
||||||
|
@ -101,8 +101,9 @@ The handler function is described in that subsection.
|
||||||
In addition, `g_signal_connect` is described in GObject API reference.
|
In addition, `g_signal_connect` is described in GObject API reference.
|
||||||
API reference is very important.
|
API reference is very important.
|
||||||
You should see and understand it to write GTK applications.
|
You should see and understand it to write GTK applications.
|
||||||
|
They are located in ['GNOME Developer Center'](https://developer.gnome.org/).
|
||||||
|
|
||||||
Let's compile the source file `pr2.c` above and run it.
|
Let's compile the source file above (`pr2.c`) and run it.
|
||||||
|
|
||||||
$ gcc `pkg-config --cflags gtk4` pr2.c `pkg-config --libs gtk4`
|
$ gcc `pkg-config --cflags gtk4` pr2.c `pkg-config --libs gtk4`
|
||||||
$ ./a.out
|
$ ./a.out
|
||||||
|
@ -112,14 +113,14 @@ Let's compile the source file `pr2.c` above and run it.
|
||||||
OK, well done.
|
OK, well done.
|
||||||
However, you may have noticed that it's painful to type such a long line to compile.
|
However, you may have noticed that it's painful to type such a long line to compile.
|
||||||
It is a good idea to use shell script to solve this problem.
|
It is a good idea to use shell script to solve this problem.
|
||||||
Make a text file which contains the following text.
|
Make a text file which contains the following line.
|
||||||
|
|
||||||
gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`
|
gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`
|
||||||
|
|
||||||
Then, save it in $HOME/bin, which is usually /home/(username)/bin.
|
Then, save it under the directory $HOME/bin, which is usually /home/(username)/bin.
|
||||||
(If your user name is James, then the directory is /home/james/bin).
|
(If your user name is James, then the directory is /home/james/bin).
|
||||||
And turn on the execute bit of the file.
|
And turn on the execute bit of the file.
|
||||||
Suppose the filename is comp, then the procedure is as follows.
|
Suppose the filename is `comp`, then the procedure is as follows.
|
||||||
|
|
||||||
$ chmod 755 $HOME/bin/comp
|
$ chmod 755 $HOME/bin/comp
|
||||||
$ ls -log $HOME/bin
|
$ ls -log $HOME/bin
|
||||||
|
@ -193,7 +194,7 @@ You need to cast `win` to GtkWindow and `app` to GtkApplication.
|
||||||
`GTK_WINDOW` and `GTK_APPLICATION` macro is appropriate for that.
|
`GTK_WINDOW` and `GTK_APPLICATION` macro is appropriate for that.
|
||||||
|
|
||||||
GtkApplication continues to run until the related window is destroyed.
|
GtkApplication continues to run until the related window is destroyed.
|
||||||
If you didn't connect GtkWindow and GtkApplication, GtkApplication shutdowns soon.
|
If you didn't connect GtkWindow and GtkApplication, GtkApplication shutdowns immediately.
|
||||||
Because no window is connected to GtkApplication, it doesn't need to wait anything.
|
Because no window is connected to GtkApplication, it doesn't need to wait anything.
|
||||||
As it shutdowns the generated window is also destroyed.
|
As it shutdowns the generated window is also destroyed.
|
||||||
|
|
||||||
|
@ -235,4 +236,3 @@ The program sets the title and the default size of the window.
|
||||||
Compile it and run `a.out`, then you will see a bigger window with its title "pr4".
|
Compile it and run `a.out`, then you will see a bigger window with its title "pr4".
|
||||||
|
|
||||||
![Screenshot of the window](../image/screenshot_pr4.png)
|
![Screenshot of the window](../image/screenshot_pr4.png)
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
|
|
||||||
### GtkLabel
|
### GtkLabel
|
||||||
|
|
||||||
We made an window and show it on the screen in the previous chapter.
|
We made an window and show it on the screen in the previous section.
|
||||||
Now we go on to the next topic, widgets in the window.
|
Now we go on to the next topic, widgets in the window.
|
||||||
The simplest widget is GtkLabel.
|
The simplest widget is GtkLabel.
|
||||||
It is a widget with a string in it.
|
It is a widget with a string in it.
|
||||||
|
|
||||||
@@@ lb1.c
|
@@@ misc/lb1.c
|
||||||
|
|
||||||
Save this program to a file `lb1.c`.
|
Save this program to a file `lb1.c`.
|
||||||
Then compile and run it.
|
Then compile and run it.
|
||||||
|
@ -25,7 +25,7 @@ There's only a little change between `pr4.c` and `lb1.c`.
|
||||||
Diff is a good program to know the difference between two files.
|
Diff is a good program to know the difference between two files.
|
||||||
|
|
||||||
$$$
|
$$$
|
||||||
diff misc/pr4.c lb1.c
|
cd misc; diff pr4.c lb1.c
|
||||||
$$$
|
$$$
|
||||||
|
|
||||||
This tells us:
|
This tells us:
|
||||||
|
@ -57,13 +57,14 @@ In this subsection, we will make a button with a label.
|
||||||
When a button is clicked on, it emits a "clicked" signal.
|
When a button is clicked on, it emits a "clicked" signal.
|
||||||
The following program shows how to catch the signal and do something.
|
The following program shows how to catch the signal and do something.
|
||||||
|
|
||||||
@@@ lb2.c
|
@@@ misc/lb2.c
|
||||||
|
|
||||||
Look at the line 17 to 19.
|
Look at the line 17 to 19.
|
||||||
First, generate a GtkButton widget `btn` with a label "Click me".
|
First, generate a GtkButton widget `btn` with a label "Click me".
|
||||||
Then, set it to the window `win` as a child.
|
Then, set it to the window `win` as a child.
|
||||||
Finally, connect a "clicked" signal of the button to a handler (function) `on_click`.
|
Finally, connect a "clicked" signal of the button to a handler (function) `click_cb`.
|
||||||
So, if `btn` is clicked, the function `on_click` is invoked.
|
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.
|
Name the program `lb2.c` and save it.
|
||||||
Now compile and run it.
|
Now compile and run it.
|
||||||
|
@ -79,12 +80,12 @@ However, using g_print is out of harmony with GTK which is a GUI library.
|
||||||
So, we will change the handler.
|
So, we will change the handler.
|
||||||
The following code is `lb3.c`.
|
The following code is `lb3.c`.
|
||||||
|
|
||||||
@@@ lb3.c on_clicked on_activate
|
@@@ misc/lb3.c click_cb on_activate
|
||||||
|
|
||||||
And the difference between `lb2.c` and `lb3.c` is as follows.
|
And the difference between `lb2.c` and `lb3.c` is as follows.
|
||||||
|
|
||||||
$$$
|
$$$
|
||||||
diff lb2.c lb3.c
|
cd misc; diff lb2.c lb3.c
|
||||||
$$$
|
$$$
|
||||||
|
|
||||||
The change is:
|
The change is:
|
||||||
|
@ -118,7 +119,7 @@ After this, the Widgets are connected as following diagram.
|
||||||
|
|
||||||
Now, code it.
|
Now, code it.
|
||||||
|
|
||||||
@@@ lb4.c
|
@@@ misc/lb4.c
|
||||||
|
|
||||||
Look at the function `on_activate`.
|
Look at the function `on_activate`.
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ After the generation of GtkApplicationWindow, GtkBox is generated.
|
||||||
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
|
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
|
||||||
|
|
||||||
The first argument arranges children vertically.
|
The first argument arranges children vertically.
|
||||||
The second argument is sizes between children.
|
The second argument is the size between children.
|
||||||
The next function fills a box with children, giving them equal space.
|
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.
|
After that, two buttons `btn1` and `btn2` are generated and the signal handlers are set.
|
||||||
|
|
Loading…
Add table
Reference in a new issue