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. think完全还原原形的 SQL

    $dd     =   Db::getInstance(); //实例连接数据库$sql = "SELECT * FROM `yezi_friendlinks`"; // SQL$ ...

  2. ubuntu 12 64 桌面版Oracle11g 安装

    1.Creating the Oracle Inventory Group sudo groupadd oinstall sudo groupadd dba sudo groupadd oper su ...

  3. 【intellij】异常信息汇总

    Application Server was not connected before run configuration stop, reason: javax.management.Instanc ...

  4. python multiprocessing 多进程

    ''' 如果要启动大量的子进程,可以用进程池的方式批量创建子进程: ''' def test_task(name): print 'Run task %s (%s)...' % (name, os.g ...

  5. [HDOJ - 5282] Senior's String 【DP】

    题目链接:BZOJ - 5282 题目分析 LCS 就是用经典的 O(n^2) DP 解决,f[i][j] 表示 x 串前 i 个字符与 y 串前 j 个字符的 LCS 长度. f[i][j] = m ...

  6. 基于协同过滤的个性化Web推荐

    下面这是论文笔记,其实主要是摘抄,这片博士论文很有逻辑性,层层深入,所以笔者保留的比较多. 看到第二章,我发现其实这片文章对我来说更多是科普,科普吧…… 一.论文来源 Personalized Web ...

  7. linux 访问windows共享

    1. windows端建立一个用户user用于共享访问 2. 共享一个目录,设置user可以访问,并在windows系统中确认可以访问 3. linux端创建一个用于挂载共享目录的目录    mkdi ...

  8. easyui源码翻译1.32--Tabs(选项卡)

    前言 使用$.fn.tabs.defaults重写默认值对象.下载该插件翻译源码 选项卡显示一批面板.但在同一个时间只会显示一个面板.每个选项卡面板都有头标题和一些小的按钮工具菜单,包括关闭按钮和其他 ...

  9. [jobdu]树中两个结点的最低公共祖先

    http://ac.jobdu.com/problem.php?pid=1509 此题最直观的方法是两次DFS,分别找到这两个节点的path,然后遍历path1和path2做比较,找到最后一个共同的元 ...

  10. [Unity菜鸟] Mecanim 系统遇到的问题

    1. 给角色添加一个Animator组件和New State,运行后,摆出这种奇怪的姿势 这是因为没有把动画片段赋给New State,可以看到此时的New State为空,把Idle片段拖进去就好了 ...