Multiline Text Editing Widget (1)

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

Multiline Text Editing Widget
        From: http://www.bravegnu.org/gtktext/

Vijay Kumar B. vijaykumar@bravegnu.org

$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>

void
on_window_destroy (GtkWidget *widget, gpointer data)
{
  gtk_main_quit ();
}

/* Callback for close button */
void
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 ();
}

int 
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),
                    NULL);

  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),
                    buffer);
  
  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 );

the craft of text editing

  • 2014年11月13日 21:40
  • 4.99MB
  • 下载

Seven habits of effective text editing

Seven habits of effective text editing Bram Moolenaar November 2000 If you spend a lot of tim...
  • easypal
  • easypal
  • 2013年08月14日 22:38
  • 395

Seven habits of effective text editing

  • 2007年09月16日 19:45
  • 201KB
  • 下载

图像融合之泊松编辑(Poisson Editing)(1):简略语言概述算法

原作者:Chris Tralie 简介 泊松图像编辑是一种全自动的“无缝融合”两张图像的技术,由Microsoft Research UK的Patrick Perez,Michel Gangnet...

BI_Editing_Tools_2_5_1游戏编辑工具

  • 2017年10月24日 14:06
  • 37.42MB
  • 下载

EFL Widget (1): Action Slider.

EFL Widget (1): Action Slider.
  • EFL_GUI
  • EFL_GUI
  • 2011年05月13日 21:09
  • 1129

RTGUI粗讲(个人见解篇之三、RTGUI WIDGET (1))

终于到RTGUI WIDGET篇了。这个应该就比较重要的一部分了,不过可能一次写不完,只能改成多次分开写,而且会写的很不好。(当然有更重要的,就是相关的一些应用举例,后面可能看情况写一下。)   ...

从零开始学_JavaScript_系列(1)——dojo(8)(手把手教你封装一个widget)

(73)封装一个widget 醒目:必须在web环境下使用,无论是python的web.py或者是通过http访问网站环境,都可以,但纯本地是不可行的。   首先,什么是widget? 简单来...

YII框架学习 第四天(1) widget

public function actionAdd() { $goods_model = new Goods(); $this->ren...
  • aszt123
  • aszt123
  • 2013年09月04日 15:50
  • 715
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Multiline Text Editing Widget (1)
举报原因:
原因补充:

(最多只允许输入30个字)