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

时间: 2024-10-20 14:04:37

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

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

GTK+中的树状列表构件(GtkTreeView) 在本章的GTK+程序设计教程中,我们将向大家重点介绍非常常用也有点复杂的构件--GtkTreeView . GtkTreeView?构件是一个高级的构件,利用他你就可以制作出漂亮的普通列表或者是树状的列表.这个构件里可以包含一或者多行.他的构架呢?正是采用了大名鼎鼎的MVC (Model View Controller) 设计框架.也就是说数据和显示方式是进行了一种分离的操作. 之前我们有说过复杂这个问题,于是在GtktreeView构件中确实

如何让IOS中的文本实现3D效果

本转载至 http://bbs.aliyun.com/read/181991.html?spm=5176.7114037.1996646101.25.p0So7c&pos=9     zhedianshi 级别: 帮帮团 发帖 487 云币 430 加关注 写私信 只看楼主 更多操作楼主  发表于: 2014-06-10 我想要在IOS中对一些文本进行3D效果渲染,使用了UIKit和标准视图控制器. 实现之的效果大概能成为这样:   能不能通过iOS和UIKit实现?我只用了一个静态PNG图片,

MVC中的分部视图

背景: 项目的工期马上就要到了,由于后台封装的很好,我们只需要用心熟悉框架,接下来后台的工作就是简单的代码工作了.原本以为最困难的时期已经过去,可没想到前台才是最困难的. B/S的基础十分薄弱,加上BS的项目做得少,遇到困难是避免不了的.霞姐说要界面灵活,那种在html里加onclick的时代已经过去.今天就来说说界面灵活之一--分部视图和Razor语法. 分部视图: 在一定程度上,分部视图与用户控件十分类似.他们都可以提高内容或代码的可重用性,但不同之处是,分部视图不需要使用ViewState

GTK+重拾--10 GTK+中的组件(二)

(一):写在前面 在上面一个小节中,我们讲解了在GTK+2.0中的一些常用的构件,在这一小节中,我们将继续学习GTK+中常用的稍微复杂的构件,这里我们主要是学习GtkComboBox,GtkEntry,GtkIconView,GtkImage,GtkSeparator,GtkStatusBar.好了,现在我们开始我们的学习之旅. (二):GtkComboBox GtkComboBox构件的作用是让程序使用者根据不同的需求从很多选项中进行选择. 下面我们来看一下如何使用GTkComboBox. #

iOS:文本视图控件UITextView的详细使用

文本视图控件:UITextView 介绍:它是一个文本域的编辑视图,可以在该区域上进行编辑(包括删除.剪贴.复制.修改等),它与文本框UITextField的不同之处是:当它里面的每一行内容超出时,可以自动换行,而且带有滚动条,可以滚动查看其他无法显示的内容. 属性: @property(nonatomic,assign) id<UITextViewDelegate> delegate;      //代理 @property(nonatomic,copy) NSString *text;  

GTK+中的构件II(Widgets)

GTK+中的构件II(Widgets) 在本章的GTK+程序设计中,我们仍然要继续向大家介绍和展示各种各样的构件. GtkComboBox GtkComboBox构件的作用是让程序使用者根据不同的需求从很多选项中进行选择. #include <gtk/gtk.h> void combo_selected(GtkWidget *widget, gpointer window) { gchar *text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(

步步为营_Android开发课[15]_用户界面之TextView(文本视图)

Focus on technology, enjoy life!-- QQ:804212028 浏览链接:http://blog.csdn.net/y18334702058/article/details/44624305 主题:用户界面之TextView(文本视图) TextView控件实例: activity_main.xml源代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xm

iOS 9应用开发教程之多行读写文本ios9文本视图

iOS 9应用开发教程之多行读写文本ios9文本视图 多行读写文本--ios9文本视图 文本视图也是输入控件,与文本框不同的是,文本视图可以让用户输入多行,如图2.23所示.在此图中字符串"说点什么吧"这一区域就是使用文本视图实现的,用户可以在此区域中写大量的文本内容.一般文本框视图使用UITextView实现. 图2.23  写日志 [示例2-9]以下将使用文本视图实现QQ中写说说并发表的功能.具体的操作步骤如下: (1)创建一个Single View Application模板类型

【GISER&amp;&amp;Painter】Chapter02:WebGL中的模型视图变换

上一节我们提到了如何在一张画布上画一个简单几何图形,通过创建画布,获取WebGLRendering上下文,创建一个简单的着色器,然后将一些顶点数据绑定到gl的Buffer中,最后通过绑定buffer数据,提供buffer中顶点数据的情况,执行渲染绘制方法,将数据结果从buffer中刷新到帧缓存中.整个流程十分清晰明了,可是通过对比原来OpenGL中的整个流程,我们会发现其中还缺少了一些很重要的处理步骤,虽然我们创建了属于自己的着色器,可并没有对顶点数据进行类似于顶点处理管线中的模型视图变换.透视