Gtk中的文本视图(GtkTexViewWidget)


Gtk中的文本视图(GtkTexView Widget)

在本章的Gtk+程序设计教程中,我们将重点介绍 GtkTexView 构件。

GtkTexView w构件被常常用来显示和编辑多行的文本。正如我们一再提到的, GtkTexBuffer 构件也是给予MVC的设计。GtkTextView 就是显示(view)元素而 GtkTexBuffer 则代表了model 元素。 GtkTexBuffer 常常被用来处理文本数据。GtkTextTag则是一种被用于文本的属性。 GtkTextIter则是代表了两个字符之间的空隙。那么很好理解,文本的排版操作多用iterators。

简单的例子(Simple example)

在我们的第一个例子中,我们将向大家展示GtkTexView 的一些功能。我们还将教大家怎么样去应用各种各样的文本标记( tags )。

#include <gtk/gtk.h>

int main( int argc, char *argv[])
{ GtkWidget *window;
GtkWidget *view;
GtkWidget *vbox; GtkTextBuffer *buffer;
GtkTextIter start, end;
GtkTextIter iter; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 250, 200);
gtk_window_set_title(GTK_WINDOW(window), "TextView");
gtk_container_set_border_width(GTK_CONTAINER(window), 5);
GTK_WINDOW(window)->allow_shrink = TRUE; vbox = gtk_vbox_new(FALSE, 0);
view = gtk_text_view_new();
gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); gtk_text_buffer_create_tag(buffer, "gap",
"pixels_above_lines", 30, NULL); gtk_text_buffer_create_tag(buffer, "lmarg",
"left_margin", 5, NULL);
gtk_text_buffer_create_tag(buffer, "blue_fg",
"foreground", "blue", NULL);
gtk_text_buffer_create_tag(buffer, "gray_bg",
"background", "gray", NULL);
gtk_text_buffer_create_tag(buffer, "italic",
"style", PANGO_STYLE_ITALIC, NULL);
gtk_text_buffer_create_tag(buffer, "bold",
"weight", PANGO_WEIGHT_BOLD, NULL); gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); gtk_text_buffer_insert(buffer, &iter, "Plain text\n", -1);
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,
"Colored Text\n", -1, "blue_fg", "lmarg", NULL);
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
"Text with colored background\n", -1, "lmarg", "gray_bg", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
"Text in italics\n", -1, "italic", "lmarg", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
"Bold text\n", -1, "bold", "lmarg", NULL); gtk_container_add(GTK_CONTAINER(window), vbox); g_signal_connect_swapped(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), G_OBJECT(window)); gtk_widget_show_all(window); gtk_main(); return 0;
}

这个例子展示了如何利用各种各样的文本标记( GtkTextTags)来显示文本。

view = gtk_text_view_new();

生成一个GtkTextView

gtk_text_buffer_create_tag(buffer, "blue_fg",
"foreground", "blue", NULL);

这就是一个运用 GtkTextTag的例子,这个标记改变了文本的颜色。

gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,
"Colored Text\n", -1, "blue_fg", "lmarg", NULL);

这个代码插入了一些文本,并运用了一个特殊的文本标记blue_fg

Figure: Simple TextView

行和栏(Lines and Columns)

在接下来的示例中将要显示文本编辑光标目前处于的行数和列数。

#include <gtk/gtk.h>

update_statusbar(GtkTextBuffer *buffer,
GtkStatusbar *statusbar)
{
gchar *msg;
gint row, col;
GtkTextIter iter; gtk_statusbar_pop(statusbar, 0); gtk_text_buffer_get_iter_at_mark(buffer,
&iter, gtk_text_buffer_get_insert(buffer)); row = gtk_text_iter_get_line(&iter);
col = gtk_text_iter_get_line_offset(&iter); msg = g_strdup_printf("Col %d Ln %d", col+1, row+1); gtk_statusbar_push(statusbar, 0, msg); g_free(msg);
} static void
mark_set_callback(GtkTextBuffer *buffer,
const GtkTextIter *new_location, GtkTextMark *mark,
gpointer data)
{
update_statusbar(buffer, GTK_STATUSBAR(data));
} int main( int argc, char *argv[])
{ GtkWidget *window;
GtkWidget *vbox; GtkWidget *toolbar;
GtkWidget *view;
GtkWidget *statusbar;
GtkToolItem *exit;
GtkTextBuffer *buffer; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 250, 200);
gtk_window_set_title(GTK_WINDOW(window), "lines & cols"); vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox); toolbar = gtk_toolbar_new();
gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS); exit = gtk_tool_button_new_from_stock(GTK_STOCK_QUIT);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), exit, -1); gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 5); view = gtk_text_view_new();
gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0);
gtk_widget_grab_focus(view); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); statusbar = gtk_statusbar_new();
gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(exit), "clicked",
G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(buffer, "changed",
G_CALLBACK(update_statusbar), statusbar); g_signal_connect_object(buffer, "mark_set",
G_CALLBACK(mark_set_callback), statusbar, 0); g_signal_connect_swapped(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); update_statusbar(buffer, GTK_STATUSBAR (statusbar)); gtk_main(); return 0;
}

在上面的代码示例中,我们完成了在状态栏中显示当前文本编辑光标所处于的行和列数。

view = gtk_text_view_new();

生成一了 GtkTextView构件。

g_signal_connect(buffer, "changed",
G_CALLBACK(update_statusbar), statusbar);

如果我们要更改文本,我们只需要调用回调函数 update_statusbar() 就可以了。

g_signal_connect_object(buffer, "mark_set",
G_CALLBACK(mark_set_callback), statusbar, 0);

当光标在移动的时候, mark_set 信号就被发射出去了。

gtk_statusbar_pop(statusbar, 0);

这段代码功能是清除了先前的任何一些状态栏中的信息。

gtk_text_buffer_get_iter_at_mark(buffer,
&iter, gtk_text_buffer_get_insert(buffer)); row = gtk_text_iter_get_line(&iter);
col = gtk_text_iter_get_line_offset(&iter);

显然上面的代码是在获取当前所处于的行号与列号。

msg = g_strdup_printf("Col %d Ln %d", col+1, row+1);

上面的代码准备好,状态栏中显示出来的行号与列号的内容。

gtk_statusbar_push(statusbar, 0, msg);

然后,我们就在状态栏上显示文本。

Figure: Lines & Columns

监测& 突显(Search & Highlight)

在接下来的例子中,我们将要在 GtkTextBuffer中做一些监测的工作。我们还将把一些文本的内容进行“突显”处理。

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h> gboolean key_pressed(GtkWidget * window,
GdkEventKey* event, GtkTextBuffer *buffer) { GtkTextIter start_sel, end_sel;
GtkTextIter start_find, end_find;
GtkTextIter start_match, end_match;
gboolean selected;
gchar *text; if ((event->type == GDK_KEY_PRESS) &&
(event->state & GDK_CONTROL_MASK)) { switch (event->keyval)
{
case GDK_m :
selected = gtk_text_buffer_get_selection_bounds(buffer,
&start_sel, &end_sel);
if (selected) {
gtk_text_buffer_get_start_iter(buffer, &start_find);
gtk_text_buffer_get_end_iter(buffer, &end_find); gtk_text_buffer_remove_tag_by_name(buffer, "gray_bg",
&start_find, &end_find);
text = (char *) gtk_text_buffer_get_text(buffer, &start_sel,
&end_sel, FALSE); while ( gtk_text_iter_forward_search(&start_find, text,
GTK_TEXT_SEARCH_TEXT_ONLY |
GTK_TEXT_SEARCH_VISIBLE_ONLY,
&start_match, &end_match, NULL) ) { gtk_text_buffer_apply_tag_by_name(buffer, "gray_bg",
&start_match, &end_match);
int offset = gtk_text_iter_get_offset(&end_match);
gtk_text_buffer_get_iter_at_offset(buffer,
&start_find, offset);
} g_free(text);
} break; case GDK_r:
gtk_text_buffer_get_start_iter(buffer, &start_find);
gtk_text_buffer_get_end_iter(buffer, &end_find); gtk_text_buffer_remove_tag_by_name(buffer, "gray_bg",
&start_find, &end_find);
break;
}
} return FALSE;
} int main( int argc, char *argv[])
{ GtkWidget *window;
GtkWidget *view;
GtkWidget *vbox; GtkTextBuffer *buffer;
GtkTextIter start, end;
GtkTextIter iter; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 250, 200);
gtk_window_set_title(GTK_WINDOW(window), "Search & Highlight");
gtk_container_set_border_width(GTK_CONTAINER(window), 5);
GTK_WINDOW(window)->allow_shrink = TRUE; vbox = gtk_vbox_new(FALSE, 0);
view = gtk_text_view_new();
gtk_widget_add_events(view, GDK_BUTTON_PRESS_MASK);
gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
gtk_text_buffer_create_tag(buffer, "gray_bg",
"background", "gray", NULL);
gtk_container_add(GTK_CONTAINER(window), vbox); g_signal_connect_swapped(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), G_OBJECT(window)); g_signal_connect(G_OBJECT(window), "key-press-event",
G_CALLBACK(key_pressed), buffer); gtk_widget_show_all(window); gtk_main(); return 0;
}

在我们的示例中,我们用到了键盘的快捷键。Ctrl + M 是用来突显我们当前所选取的文本内容。Ctrl + R 则是用来取消上面的操作。

gtk_text_buffer_create_tag(buffer, "gray_bg",
"background", "gray", NULL);

我们在例子中会再次用到 GtkTextTag 。这个标记可以使文本的背景反白。

selected = gtk_text_buffer_get_selection_bounds(buffer,
&start_sel, &end_sel);

这里我们得到我们选中的文本所具有的起始和终点位置。

gtk_text_buffer_get_start_iter(buffer, &start_find);
gtk_text_buffer_get_end_iter(buffer, &end_find);

我们得到了文本缓冲区(text buffer)的起始和终点位置。

gtk_text_buffer_remove_tag_by_name(buffer, "gray_bg",
&start_find, &end_find);

上面就是,把先前的标记去处。

text = (char *) gtk_text_buffer_get_text(buffer, &start_sel,
&end_sel, FALSE);

接着我们得到了所选择的文本内容,我们将要进行监测。

while ( gtk_text_iter_forward_search(&start_find, text,
GTK_TEXT_SEARCH_TEXT_ONLY |
GTK_TEXT_SEARCH_VISIBLE_ONLY,
&start_match, &end_match, NULL) ) { gtk_text_buffer_apply_tag_by_name(buffer, "gray_bg",
&start_match, &end_match);
int offset = gtk_text_iter_get_offset(&end_match);
gtk_text_buffer_get_iter_at_offset(buffer,
&start_find, offset);
}

这段代码将检测所有我们所选择的文本后的所发生的事件,一旦发现与我们定义的内容有匹配就应用我们设定好的标记。在匹配工作完成之后,单词的尾端将将被成下次监视操作的首端。

Figure: Search & Highlight

Gtk中的文本视图(GtkTexViewWidget)的更多相关文章

  1. iOS中 UITextView文本视图 技术分享

    UITextView: 文本视图相比与UITextField直观的区别就是UITextView可以输入多行文字并且可以滚动显示浏览全文. UITextField的用处多,UITextView的用法也不 ...

  2. GTK+中的树状列表构件(GtkTreeView)

    GTK+中的树状列表构件(GtkTreeView) GTK+中的树状列表构件(GtkTreeView) 在本章的GTK+程序设计教程中,我们将向大家重点介绍非常常用也有点复杂的构件--GtkTreeV ...

  3. 关于iOS中的文本操作-管理text fields 和 text views

    Managing Text Fields and Text Views 管理UITextField和UITextView实例 UITextField和UITextView的实例拥有两个最主要的功能:展 ...

  4. 关于ios中的文本操作-简介

    来源:About Text Handling in iOS 官方文档 iOS平台为我们提供了许多在app中展示文本和让用户编辑文本的方式.同时,它也允许你在app视图中展示格式化的文本和网页内容.你可 ...

  5. GTK+中的构件II(Widgets)

    GTK+中的构件II(Widgets) GTK+中的构件II(Widgets) 在本章的GTK+程序设计中,我们仍然要继续向大家介绍和展示各种各样的构件. GtkComboBox GtkComboBo ...

  6. UITextView(文本视图) 学习之初体验

    UITextView文本视图相比与UITextField直观的区别就是UITextView可以输入多行文字并且可以滚动显示浏览全文.常见UITextView使用在APP的软件简介.内容详情显示.小说阅 ...

  7. IOS 学习笔记(5) 控件 文本视图(UITextView)的使用方法

    相对于UILabell所支持的较短文本内容,UITextView对于长文本的支持更好.UITextView能够以滚动的方式全部浏览到长文本,并且就像UILabel那样,从ISO6,他也提供了对NSAt ...

  8. MFC中的一些视图

    本章主要介绍MFC中主要的视图类,这些继承自Cview类. 继承关系如上图所示. 滚动视图 CscrollView给Cview添加了基本的滚动功能,它包含WM_VSCROLL和WM_HSCROLL消息 ...

  9. MVC中的分部视图

    背景: 项目的工期马上就要到了,由于后台封装的很好,我们只需要用心熟悉框架,接下来后台的工作就是简单的代码工作了.原本以为最困难的时期已经过去,可没想到前台才是最困难的. B/S的基础十分薄弱,加上B ...

随机推荐

  1. CentOS7 IP自动获取

    /etc/sysconfig/network-scripts HWADDR=00:15:5D:00:76:04TYPE=EthernetBOOTPROTO=dhcpDEFROUTE=yesPEERDN ...

  2. WPF 控件

    ****ScrollViewer**** 前台: <ScrollViewer  HorizontalScrollBarVisibility="Auto" VerticalSc ...

  3. 刷漆(Codechef October Challenge 2014:Remy paints the fence)

    [问题描述] Czy做完了所有的回答出了所有的询问,结果是,他因为脑力消耗过大而变得更虚了:).帮助Czy恢复身材的艰巨任务落到了你的肩上. 正巧,你的花园里有一个由N块排成一条直线的木板组成的栅栏, ...

  4. Codeforces Round #359 div2

    Problem_A(CodeForces 686A): 题意: \[ 有n个输入, +\space d_i代表冰淇淋数目增加d_i个, -\space d_i表示某个孩纸需要d_i个, 如果你现在手里 ...

  5. poj 1811 Prim test

    基本上一个裸的Miller_Rabin大素数判定和一个裸的Pollard_rho素数分解算法,当模板用吧! #include<cstdio> #include<algorithm&g ...

  6. *[topcoder]HexagonalBoard

    http://community.topcoder.com/stat?c=problem_statement&pm=12784 真心觉得tc的div1 250不少好题,对我来说比较适合.这道题 ...

  7. 把硬盘格式化成ext格式的cpu占用率就下来了

    把硬盘格式化成ext格式的cpu占用率就下来了我是使用ext4格式 @Paulz 还有这种事情? 现在是什么格式?- - ,你自己用top命令看一下啊就知道什么东西在占用cpu了下载软件一半cpu都用 ...

  8. Javascript实现摩斯码加密解密

    原文地址 作者:liaoyu 摩尔斯电码是一种时通时断的信号代码,通过不同的排列顺序来表达不同的英文字母.数字和标点符号,是由美国人萨缪尔·摩尔斯在1836年发明. 每一个字符(字母或数字)对应不同的 ...

  9. Android ListView动态更新数据

    ListView就是可以显示一行行Item的控件,有时候数据非常多,通常需要分页显示,但为了减少用户的输入,我们可以动态更新ListView,把下一页要显示的数据的添加到当前ListView中. 先看 ...

  10. laravel 模板 blade

    控制器布局 在Laravel框架中使用模板的一种方法就是通过控制器布局.通过在控制器中指定 layout 属性,对应的视图会被创建并且作为请求的默认返回数据. 在控制器中定义一个布局 class Us ...