Multiline Text Editing Widget (1)

转载 2005年06月02日 16:16:00

Multiline Text Editing Widget

Vijay Kumar B.

$Name: GTKTEXT_0_2_0 $ $Id: gtktext.docbook,v 1.4 2005/05/23 01:39:32 vijay Exp $
Other Formats: [DocBook Tar ball] [HTML Tar ball] [Single HTML] [TXT]

1. Simple Multiline Text Widget

In this section, you will learn how to create a simple multiline text widget, using GtkTextView, for data entry.

The widget itself is created using

GtkWidget *gtk_text_view_new( void );

When the GtkTextView widget is created this way, a GtkTextBuffer object associated with this widget is also created. The GtkTextBuffer is responsible for storing the text and associated attributes, while the GtkTextView widget is responsible for displaying the text ie. it provides an I/O interface to buffer.

All text modification operations are related to the buffer object. The buffer associated with a GtkTextView widget can be obtained using

GtkTextBuffer *gtk_text_view_get_buffer( GtkTextView *text_view );

Some common operations performed on a simple multiline text widget are, setting the entire text and reading the entire text from the buffer. The entire text of the buffer can be set using

void gtk_text_buffer_set_text( GtkTextBuffer *buffer, 
                               const gchar   *text,
                               gint          len );
The len should be specified when the text contains '/0'. When the text does not contain '/0'and is terminated by a '/0', len could be -1.

Getting the entire text of a buffer, could be a little more complicated than setting the entire text of the buffer. You will have to understand iterators. Iterators are objects that represent positions between two characters in a buffer. Iters in a buffer can be obtained using many different functions, but for our simple case the following functions can be used to get the iters at the start and end of the buffer.

void gtk_text_buffer_get_start_iter( GtkTextBuffer *buffer,
                                     GtkTextIter   *iter );
void gtk_text_buffer_get_end_iter( GtkTextBuffer *buffer,
                                   GtkTextIter   *iter );

Unlike other objects which are created using constructor like functions returning pointers to the objects, the GtkTextIter objects are created by instantiating the structure itself i.e they are allocated on the stack. So new GtkTextIter objects are created as follows

GtkTextIter start_iter;
GtkTextIter end_iter;
Pointers to the iterators are then passed to the above functions for initialization.

The initialized iters, can be used in the following function to retrieve the entire contents of the buffer.

gchar *gtk_text_buffer_get_text( GtkTextBuffer     *buffer, 
                                 const GtkTextIter *start,
                                 const GtkTextIter *end,
                                 gboolean          include_hidden_chars );
The include_hidden_chars is used to specify whether are not to include text that has the invisible attribute set. Text attributes and how to set them will be discussed later in this tutorial. The returned string is dynamically allocated and should be freed using g_free.

Below is a sample program, that implements the simple multiline text widget. The program assigns a default text to the buffer. The text in the buffer can be modified by the user and when the close button is pressed it prints the contents of the buffer and quits.

#include <gtk/gtk.h>

on_window_destroy (GtkWidget *widget, gpointer data)
  gtk_main_quit ();

/* Callback for close button */
on_button_clicked (GtkWidget *button, GtkTextBuffer *buffer)
  GtkTextIter start;
  GtkTextIter end;

  gchar *text;

  /* Obtain iters for the start and end of points of the buffer */
  gtk_text_buffer_get_start_iter (buffer, &start);
  gtk_text_buffer_get_end_iter (buffer, &end);

  /* Get the entire buffer text. */
  text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);

  /* Print the text */
  g_print ("%s", text);

  g_free (text);

  gtk_main_quit ();

main(int argc, char *argv[])
  GtkWidget *window;
  GtkWidget *vbox;
  GtkWidget *text_view;
  GtkWidget *button;
  GtkTextBuffer *buffer;
  gtk_init (&argc, &argv);

  /* Create a Window. */
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Simple Multiline Text Input");

  /* Set a decent default size for the window. */
  gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
  g_signal_connect (G_OBJECT (window), "destroy", 
                    G_CALLBACK (on_window_destroy),

  vbox = gtk_vbox_new (FALSE, 2);
  gtk_container_add (GTK_CONTAINER (window), vbox);

  /* Create a multiline text widget. */
  text_view = gtk_text_view_new ();
  gtk_box_pack_start (GTK_BOX (vbox), text_view, 1, 1, 0);

  /* Obtaining the buffer associated with the widget. */
  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
  /* Set the default buffer text. */ 
  gtk_text_buffer_set_text (buffer, "Hello Text View!", -1);
  /* Create a close button. */
  button = gtk_button_new_with_label ("Close");
  gtk_box_pack_start (GTK_BOX (vbox), button, 0, 0, 0);
  g_signal_connect (G_OBJECT (button), "clicked", 
                    G_CALLBACK (on_button_clicked),
  gtk_widget_show_all (window);

  gtk_main ();
  return 0;

1.1. More on Iterators

A point to note about text iterators - iterators are not valid indefinitely. Whenever the buffer is modified in a way that affects the number of characters in the buffer, all outstanding iterators become invalid. You will have to re-obtain iterators to use them. To preserve positions across buffer modifications the GtkTextMark can be used. Text marks will be discussed later in this tutorial.

1.2. UTF-8 and GTK+

GTK+ handles text in UTF-8 format. For the uninitiated, the UTF-8 is an ASCII compatible multi-byte unicode encoding. The thing to be noted is that one character can be encoded as multiple bytes. The GTK+ manual uses the term offset for character counts, and uses the term index for byte counts. The len argument of the gtk_text_buffer_set_text function is the length of the text in bytes.

1.3. Other Editing Functions

The following function can be used to delete text from a buffer.

void gtk_text_buffer_delete( GtkTextBuffer *buffer,
                             GtkTextIter   *start,
                             GtkTextIter   *end );
Since this function modifies the buffer, all outstanding iterators become invalid after a call to this function. But, the iterators passed to the function are re-initialized to point to the location where the text was deleted.

The following function can be used to insert text into a buffer at a position specified by an iterator.

void gtk_text_buffer_insert( GtkTextBuffer *buffer,
                             GtkTextIter   *iter,
                             const gchar   *text,
                             gint          len );
The len argument is similar to the len argument in gtk_text_buffer_set_text function. As with gtk_text_buffer_delete, the buffer is modified and hence all outstanding iterators become invalid, and start and end are re-initialized. Hence the same iterator can be used for a series of consecutive inserts.

The following function can be used to insert text at the current cursor position.

void gtk_text_buffer_insert_at_cursor( GtkTextBuffer *buffer,
                                       const gchar   *text,
                                       gint          len );

1.4. Other Functions to Obtain Iters

The following function can be used to get iterators at the beginning and end of the buffer in one go.

void gtk_text_buffer_get_bounds( GtkTextBuffer *buffer,
                                 GtkTextIter   *start,
                                 GtkTextIter   *end );

A variant of the above function can be used to obtain iterators at the beginning and end of the current selection.

void gtk_text_buffer_selection_bounds( GtkTextBuffer *buffer,
                                       GtkTextIter   *start,
                                       GtkTextIter   *end );

The following functions can be used to obtain an iterator at a specified character offset into the buffer, at the start of the given line, at an character offset into a given line, or at a byte offset into a given line, respectively.

void gtk_text_buffer_get_iter_at_offset( GtkTextBuffer *buffer,
                                         GtkTextIter   *iter,
                                         gint          char_offset);
void gtk_text_buffer_get_iter_at_line( GtkTextBuffer *buffer,
                                       GtkTextIter   *iter,
                                       gint          line_number);
void gtk_text_buffer_get_iter_at_line_offset( GtkTextBuffer *buffer,
                                              GtkTextIter   *iter,
                                              gint          line_no,
                                              gint          offset );
void gtk_text_buffer_get_iter_at_line_index( GtkTextBuffer *buffer,
                                             GtkTextIter   *iter,
                                             gint          line_no,
                                             gint          index );

Multiline Text Editing Widget (7)

From: Buffer and Window CoordinatesSometimes it ...
  • Yazy
  • Yazy
  • 2005年06月04日 10:26
  • 1435

Multiline Text Editing Widget (2)

From: Formatted Text in GtkTextViewGtkTextView ca...
  • Yazy
  • Yazy
  • 2005年06月02日 23:54
  • 1635

Multiline Text Editing Widget (6)

From: Images/WidgetsA text buffer can hold image...
  • Yazy
  • Yazy
  • 2005年06月04日 10:22
  • 1412

Multiline Text Editing Widget (5)

From: Examining and Modifying TextExamining and ...
  • Yazy
  • Yazy
  • 2005年06月04日 10:21
  • 1293

Multiline Text Editing Widget (4)

From: SearchingIn this section, you will learn h...
  • Yazy
  • Yazy
  • 2005年06月04日 10:18
  • 1803

Multiline Text Editing Widget (9)

From: 9. Tutorial Copyright and Permissions NoticeCopy...
  • Yazy
  • Yazy
  • 2005年06月04日 10:29
  • 946

Multiline Text Editing Widget (3)

From: Cut, Copy and PasteIn this section you wil...
  • Yazy
  • Yazy
  • 2005年06月04日 10:09
  • 1113

Multiline Text Editing Widget (8)

From: Final Notes8.1. GtkTextView in gtk-demoThe...
  • Yazy
  • Yazy
  • 2005年06月04日 10:27
  • 1123

Android Material Design控件学习(一)——TabLayout的用法

前言 Google官方在14年Google I/O上推出了全新的设计语言——Material Design。一并推出了一系列实现Material Design效果的控件库——Android De...
  • liqingmiao123
  • liqingmiao123
  • 2016年01月16日 00:31
  • 796

Sublime Text 3 MarkdownEditing布局设置

在Sublime Text 3 MarkdownEditing插件打开md文件默认的主题很丑,而且文字居中,左侧有大片空白,需要修改配置文件调整一下。 流程: ctrl+shift+p打开命令输入...
  • hfut_jf
  • hfut_jf
  • 2016年10月18日 22:38
  • 4416
您举报文章:Multiline Text Editing Widget (1)