Редактирование: GTK FAQ GtkTextView Widget

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
 +
In this part of the GTK+ programming tutorial, we will work with a GtkTexView widget.
 +
<b>GtkTexView</b> widget is used for displaying and editing multiline text.
 +
GtkTexView widget has also the MVC design. The GtkTextView represents the view component and  <b>GtkTexBuffer</b> represents the model component. The GtkTexBuffer is used to  manipulate the text data. <b>GtkTextTag</b> is an attribute that can be applied to the text. The <b>GtkTextIter</b> represents a position between two characters in the text. All manipulation with the text is done using text iterators.
 +
 +
== Simple example ==
 +
 +
In our first example, we show some of the GtkTexView's functionality. We show how to apply various text tags to the text data in the GtkTextView.
 +
 +
<source lang="cpp">
 +
#include &lt;gtk/gtk.h&gt;
 +
 +
 +
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;
 +
}
 +
 +
</source>
 +
 +
The example shows some text with different <b>GtkTextTags</b> applied.
 +
 +
<source lang="cpp">
 +
view = gtk_text_view_new();
 +
</source>
 +
 +
The <b>GtkTextView</b> is created.
 +
 +
<source lang="cpp">
 +
gtk_text_buffer_create_tag(buffer, "blue_fg",
 +
    "foreground", "blue", NULL);
 +
</source>
 +
 +
This is an example of a <b>GtkTextTag</b>. The tag changes the color of the text to blue.
 +
 +
<source lang="cpp">
 +
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,
 +
      "Colored Text\n", -1, "blue_fg", "lmarg",  NULL);
 +
 +
</source>
 +
 +
This code inserts some text with a specific <b>blue_fg</b> text tag.
 +
 +
[[image: gtk_faq_simpletextview.png | center]]
 +
 +
== Lines and Columns ==
 +
 +
The following example will display the current line and column of the text cursor. 
 +
 +
<source lang="cpp">
 +
#include &lt;gtk/gtk.h&gt;
 +
 +
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;
 +
}
 +
 +
</source>
 +
 +
In this code example, we show the current position of the text cursor in the statusbar.
 +
 +
<source lang="cpp">
 +
view = gtk_text_view_new();
 +
</source>
 +
 +
The <b>GtkTextView</b> widget is created.
 +
 +
<source lang="cpp">
 +
g_signal_connect(buffer, "changed",
 +
      G_CALLBACK(update_statusbar), statusbar);
 +
</source>
 +
 +
When we change the text, we call the <b>update_statusbar()</b> handler.
 +
 +
<source lang="cpp">
 +
g_signal_connect_object(buffer, "mark_set",
 +
      G_CALLBACK(mark_set_callback), statusbar, 0);
 +
</source>
 +
 +
The <b>mark_set</b> signal is emitted, when the cursor moves.
 +
 +
<source lang="cpp">
 +
gtk_statusbar_pop(statusbar, 0);
 +
</source>
 +
 +
This code line clears any previous message from the statusbar.
 +
 +
<source lang="cpp">
 +
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);
 +
</source>
 +
 +
These lines determine the current line/row and column. 
 +
 +
<source lang="cpp">
 +
msg = g_strdup_printf("Col %d Ln %d", col+1, row+1);
 +
</source>
 +
 +
This code builds the text to be displayed on the statusbar.
 +
 +
<source lang="cpp">
 +
gtk_statusbar_push(statusbar, 0, msg);
 +
</source>
 +
 +
We show the text on the statusbar.
 +
 +
[[image: gtk_faq_linesandcols.png | center]]
 +
 +
 +
== Search &amp; Highlight ==
 +
 +
In the next example, we will do some searching in the <b>GtkTextBuffer</b>.
 +
We will highlight some text patterns in the text buffer.
 +
 +
<source lang="cpp">
 +
#include &lt;gtk/gtk.h&gt;
 +
#include &lt;gdk/gdkkeysyms.h&gt;
 +
 +
 +
 +
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;
 +
}
 +
 +
</source>
 +
 +
In our code example we use keyboard shortcuts. The Ctrl + M shortcut highlights the all occurences of currently selected text. The Ctrl + R removes the highlights from the text. 
 +
 +
<source lang="cpp">
 +
gtk_text_buffer_create_tag(buffer, "gray_bg",
 +
    "background", "gray", NULL);
 +
</source>
 +
 +
This is the <b>GtkTextTag</b> that we use in our example. The tag makes the background of the text gray.
 +
 +
<source lang="cpp">
 +
selected = gtk_text_buffer_get_selection_bounds(buffer,
 +
    &start_sel, &end_sel);
 +
</source>
 +
 +
Here we get the start and end positions of the selected text.
 +
 +
<source lang="cpp">
 +
gtk_text_buffer_get_start_iter(buffer, &start_find);
 +
gtk_text_buffer_get_end_iter(buffer, &end_find);
 +
 +
</source>
 +
 +
We get the first and last position in the text buffer.
 +
 +
<source lang="cpp">
 +
gtk_text_buffer_remove_tag_by_name(buffer, "gray_bg",
 +
    &start_find, &end_find); 
 +
</source>
 +
 +
We remove any previous text tag.
 +
 +
<source lang="cpp">
 +
text = (char *) gtk_text_buffer_get_text(buffer, &start_sel,
 +
    &end_sel, FALSE);
 +
</source>
 +
 +
We obtain the selected text. It is the text, we are going to search for.
 +
 +
<source lang="cpp">
 +
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);
 +
}
 +
 +
</source>
 +
 +
This code searches for all occurences of our selected text. If we find any match, we apply the text tag. After the match, the ending point of the word becomes the starting point for the next search.
 +
 +
[[image: gtk_faq_searchhighlight.png | center]]
 +
 +
 +
[[Категория:GTK+]]

Пожалуйста, обратите внимание, что все ваши добавления могут быть отредактированы или удалены другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см. Wiki.crossplatform.ru:Авторское право). НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!