1 GtkTextView,GtkTextBuffer and GtkScrolledWindow
GtkTextView and GtkTextBuffer
GtkTextView是一个用于多行文本编辑的构件。GtkTextBuffer是一个连接到GtkTextView的文本缓冲区。请参阅下面的示例程序tfv1.c。
1 #include <gtk/gtk.h>
2
3 static void
4 app_activate (GApplication *app) {
5 GtkWidget *win;
6 GtkWidget *tv;
7 GtkTextBuffer *tb;
8 gchar *text;
9
10 text =
11 "Once upon a time, there was an old man who was called Taketori-no-Okina. "
12 "It is a japanese word that means a man whose work is making bamboo baskets.\n"
13 "One day, he went into a mountain and found a shining bamboo. "
14 "\"What a mysterious bamboo it is!,\" he said. "
15 "He cut it, then there was a small cute baby girl in it. "
16 "The girl was shining faintly. "
17 "He thought this baby girl is a gift from Heaven and took her home.\n"
18 "His wife was surprized at his story. "
19 "They were very happy because they had no children. "
20 ;
21 win = gtk_application_window_new (GTK_APPLICATION (app));
22 gtk_window_set_title (GTK_WINDOW (win), "Taketori");
23 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
24
25 tv = gtk_text_view_new ();
26 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
27 gtk_text_buffer_set_text (tb, text, -1);
28 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR);
29
30 gtk_window_set_child (GTK_WINDOW (win), tv);
31
32 gtk_window_present (GTK_WINDOW (win));
33 }
34
35 int
36 main (int argc, char **argv) {
37 GtkApplication *app;
38 int stat;
39
40 app = gtk_application_new ("com.github.ToshioCP.tfv1", G_APPLICATION_DEFAULT_FLAGS);
41 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
42 stat = g_application_run (G_APPLICATION (app), argc, argv);
43 g_object_unref (app);
44 return stat;
45 }
请看第25行。创建了一个GtkTextView实例,并将其指针赋值给tv。当GtkTextView实例被创建时,一个GtkTextBuffer实例也被创建并自动连接到GtkTextView。“GtkTextBuffer实例”将被简称为“GtkTextBuffer”或“buffer”。在下一行,指向缓冲区的指针被赋值为tb。然后,第10 ~ 20行的文本被分配给缓冲区。如果gtk_text_buffer_set_text的第三个参数是一个正整数,则它是文本的长度。如果是-1,字符串以NULL结束(\0结束)。
GtkTextView有一个wrap换行模式。当设置为GTK_WRAP_WORD_CHAR时,文本换行在单词之间,如果这还不够,还可以换行在字母之间。
换行模式是用GTK 4 API文档中的Gtk_WrapMode编写的。
第30行,tv添加到了win,作为一个子构件。
现在编译并运行它。
$ cd src/tfv
$ comp tfv1
$ ./a.out
在窗口里有一个光标。在GtkTextView里面,您可以添加或删除任何字符,和您的增删可以保存在GtkTextBuffer。如果你添加的字符超过了窗口的限制,高度会增加,窗口会扩展。如果窗口的高度大于显示屏幕的高度,你将无法控制窗口的大小或将其更改为原始大小。这是一个问题,也就是bug。这可以通过在GtkApplicationWindow和GtkTextView之间添加一个GtkScrolledWindow来解决。
GtkScrolledWindow
我们需要做的是:
- 创建一个GtkScrolledWindow,并将其作为GtkApplicationWindow的一个子构件插入
- 将GtkTextView构件作为子窗口插入到GtkScrolledWindow。
修改tfv1.c并保存为tfv2.c。这两个文件只有一点不同。
$ cd tfv; diff tfv1.c tfv2.c
5a6
> GtkWidget *scr;
24a26,28
> scr = gtk_scrolled_window_new ();
> gtk_window_set_child (GTK_WINDOW (win), scr);
>
30c34
< gtk_window_set_child (GTK_WINDOW (win), tv);
---
> gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv);
40c44
< app = gtk_application_new ("com.github.ToshioCP.tfv1", G_APPLICATION_DEFAULT_FLAGS);
---
> app = gtk_application_new ("com.github.ToshioCP.tfv2", G_APPLICATION_DEFAULT_FLAGS);
tfv2.c的整个代码如下:
1 #include <gtk/gtk.h>
2
3 static void
4 app_activate (GApplication *app) {
5 GtkWidget *win;
6 GtkWidget *scr;
7 GtkWidget *tv;
8 GtkTextBuffer *tb;
9 gchar *text;
10
11 text =
12 "Once upon a time, there was an old man who was called Taketori-no-Okina. "
13 "It is a japanese word that means a man whose work is making bamboo baskets.\n"
14 "One day, he went into a mountain and found a shining bamboo. "
15 "\"What a mysterious bamboo it is!,\" he said. "
16 "He cut it, then there was a small cute baby girl in it. "
17 "The girl was shining faintly. "
18 "He thought this baby girl is a gift from Heaven and took her home.\n"
19 "His wife was surprized at his story. "
20 "They were very happy because they had no children. "
21 ;
22 win = gtk_application_window_new (GTK_APPLICATION (app));
23 gtk_window_set_title (GTK_WINDOW (win), "Taketori");
24 gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
25
26 scr = gtk_scrolled_window_new ();
27 gtk_window_set_child (GTK_WINDOW (win), scr);
28
29 tv = gtk_text_view_new ();
30 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
31 gtk_text_buffer_set_text (tb, text, -1);
32 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR);
33
34 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), tv);
35
36 gtk_window_present (GTK_WINDOW (win));
37 }
38
39 int
40 main (int argc, char **argv) {
41 GtkApplication *app;
42 int stat;
43
44 app = gtk_application_new ("com.github.ToshioCP.tfv2", G_APPLICATION_DEFAULT_FLAGS);
45 g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
46 stat = g_application_run (G_APPLICATION (app), argc, argv);
47 g_object_unref (app);
48 return stat;
49 }
编译并运行它。
现在,即使你输入了很多字符,窗口也不会扩展,它只是滚动。