免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 732 | 回复: 0
打印 上一主题 下一主题

gtk+2.0之textview(文章收藏) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-17 21:02 |只看该作者 |倒序浏览

Gtk中的文本视图(GtkTexView Widget)
在本章的Gtk+程序设计教程中,我们将重点介绍 GtkTexView 构件。
GtkTexView w构件被常常用来显示和编辑多行的文本。正如我们一再提到的,GtkTexBuffer 构件也是给予MVC的设计。GtkTextView 就是显示(view)元素而 GtkTexBuffer 则代表了model 元素。GtkTexBuffer 常常被用来处理文本数据。GtkTextTag则是一种被用于文本的属性。 GtkTextIter则是代表了两个字符之间的空隙。那么很好理解,文本的排版操作多用iterators。
简单的例子(Simple example)
在我们的第一个例子中,我们将向大家展示GtkTexView 的一些功能。我们还将教大家怎么样去应用各种各样的文本标记( tags )。
#include
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
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
#include
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);
}
这段代码将检测所有我们所选择的文本后的所发生的事件,一旦发现与我们定义的内容有匹配就应用我们设定好的标记。在匹配工作完成之后,单词的尾端将将被成下次监视操作的首端。



本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/106271/showart_2097065.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP