The Text widget allows multiple lines of text to be displayed and edited. It supports both multi-colored and multi-font text, allowing them to be mixed in any way we wish. It also has a wide set of key based text editing commands, which are compatible with the Emacs text editor.
The text widget supports full cut-and-paste facilities, including the use of double-click and triple-click to select a word and a whole line, respectively.
There is only one function for creating a new Text widget.
$text = new Gtk::Text( $hadj, $vadj );
The arguments allow us to give the Text widget adjustments
that can be used to track the viewing position of the widget.
Passing undefined values to either or both of these arguments
will cause the
new()
function to create its own.
$text->set_adjustments( $hadj, $vadj );
The above function allows the horizontal and vertical adjustments of a text widget to be changed at any time.
The text widget will not automatically create its own
scrollbars when the amount of text to be displayed is too
long for the display window. We therefore have to create and
add them to the display layout ourselves.
$vscrollbar = new Gtk::VScrollbar( $text->vadj );
$hbox->pack_start( $vscrollbar, $false, $false, 0 );
$vscrollbar->show();
The above code snippet creates a new vertical scrollbar, and attaches it to the vertical adjustment of the text widget. It then packs it into a box in the normal way.
Currently the Text widget does not support horizontal scrollbars.
There are two main ways in which a Text widget can be used:
to allow the user to edit a body of text, or to allow us to
display multiple lines of text to the user. In order for us
to switch between these modes of operation, the text widget
has the following function:
$text->set_editable( $editable );
The $editable argument is a true or false value that specifies whether the user is permitted to edit the contents of the Text widget. When the text widget is editable, it will display a cursor at the current insertion point.
You are not, however, restricted to just using the text widget in these two modes. You can toggle the editable state of the text widget at any time, and can insert text at any time.
The text widget wraps lines of text that are too long to fit
onto a single line of the display window. Its default
behaviour is to break words across line breaks. This can be
changed using the next function:
$text->set_word_wrap( $word_wrap );
Using this function allows us to specify that the text widget should wrap long lines on word boundaries. The $word_wrap argument is a true or false value.
You can also wrap a line when it reaches the end of the Text
widget, disregarding word boundries. This is set using:
$text->set_line_wrap( $line_wrap );
The current insertion point of a Text widget can be set using
$text->set_point( $index );
Where $index is the position to set the insertion point.
Analogous to this is the function for getting the current
insertion point:
$text->get_point();
A function that is useful in combination with the above two
functions is:
$text->get_length();
which returns the current length of the Text widget. The length is the number of characters that are within the text block of the widget, including characters such as newlines.
In order to insert text at the current insertion point of a
Text widget, the function
insert()
is used, which also allows us to specify background and
foreground colors and a font for the text.
$text->insert( $font, $foreground, $background, $string );
Passing an undefined value as the foreground color, background color or font will result in the values set within the widget style to be used.
The text widget is one of the few within GTK that redraws itself dynamically, outside of main Gtk. This means that all changes to the contents of the text widget take effect immediately. This may be undesirable when performing multiple changes to the text widget. In order to allow us to perform multiple updates to the text widget without it continuously redrawing, we can freeze the widget, which temporarily stops it from automatically redrawing itself every time it is changed. We can then thaw the widget after our updates are complete.
The following two functions perform this freeze and thaw action:
$tree->freeze();
$tree->thaw();
Text is deleted from the text widget relative to the current
insertion point by the following two functions. The return
value is a true or false indicator of whether the operation
was successful.
$text->backward_delete( $num_chars );
$text->forward_delete( $num_chars );
If you want to retrieve the contents of the text widget, then use index( $index ), which allows you to retrieve the character at position $index within the text widget.
The text widget has a number of pre-installed keyboard shortcuts for common editing, motion and selection functions. These are accessed using Control and Alt key combinations.
In addition to these, holding down the Control key while using cursor key movement will move the cursor by words rather than characters. Holding down Shift while using cursor movement will extend the selection.
Ctrl-A Beginning of line
Ctrl-E End of line
Ctrl-N Next Line
Ctrl-P Previous Line
Ctrl-B Backward one character
Ctrl-F Forward one character
Alt-B Backward one word
Alt-F Forward one word
Ctrl-H Delete Backward Character (Backspace)
Ctrl-D Delete Forward Character (Delete)
Ctrl-W Delete Backward Word
Alt-D Delete Forward Word
Ctrl-K Delete to end of line
Ctrl-U Delete line
Ctrl-X Cut to clipboard
Ctrl-C Copy to clipboard
Ctrl-V Paste from clipboard
#!/usr/bin/perl -w use Gtk; use strict; set_locale Gtk; init Gtk; my $false = 0; my $true = 1; my $line; my $window; my $main_vbox; my $vbox; my $hbox; my $button; my $check; my $separator; my $table; my $vscrollbar; my $text; my $cmap; my $color; my $fixed_font; # Create a window $window = new Gtk::Window( 'toplevel' ); $window->set_usize( 600, 500 ); $window->set_policy( $true, $true, $false ); $window->signal_connect( 'destroy', sub { Gtk->exit( 0 ); } ); $window->set_title( "Text Widget Example" ); $window->border_width( 0 ); $main_vbox = new Gtk::VBox( $false, 0 ); $window->add( $main_vbox ); $main_vbox->show(); $vbox = new Gtk::VBox( $false, 10 ); $vbox->border_width( 10 ); $main_vbox->pack_start( $vbox, $true, $true, 0 ); $vbox->show(); # Create a table $table = new Gtk::Table( 2, 2, $false ); $table->set_row_spacing( 0, 2 ); $table->set_col_spacing( 0, 2 ); $vbox->pack_start( $table, $true, $true, 0 ); $table->show(); # Create the Text widget $text = new Gtk::Text( undef, undef ); $text->set_editable( $true ); $table->attach( $text, 0, 1, 0, 1, [ 'expand', 'shrink', 'fill' ], [ 'expand', 'shrink', 'fill' ], 0, 0 ); $text->show(); # Add a vertical scrollbar to the GtkText widget $vscrollbar = new Gtk::VScrollbar( $text->vadj ); $table->attach( $vscrollbar, 1, 2, 0, 1, 'fill', [ 'expand', 'shrink', 'fill' ], 0, 0 ); $vscrollbar->show(); # Get the system color map and allocate the color red $cmap = Gtk::Gdk::Colormap->get_system(); $color->{ 'red' } = 0xFFFF; $color->{ 'green' } = 0; $color->{ 'blue' } = 0; unless ( defined( $cmap->color_alloc( $color ) ) ) { warn( "Couldn't allocate color\n" ); } # Load a fixed font my $name = "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-koi8-r"; $fixed_font = Gtk::Gdk::Font->load( $name ); # Realizing a widget creates a window for it, its now ready for us to # insert some text $text->realize(); # Freeze the text widget, ready for multiple updates $text->freeze(); # Insert some colored text $text->insert( undef, $text->style->black, undef, "Supports " ); $text->insert( undef, $color, undef, "colored " ); $text->insert( undef, $text->style->black, undef, "text and different " ); $text->insert( $fixed_font, $text->style->black, undef, "fonts\n\n" ); # Load the file text (this program) into the text window open( FILE, "text" ); foreach $line ( <FILE> ) { $text->insert( $fixed_font, undef, undef, $line ); } close( FILE ); # Thaw the text widget, allowing the updates to become visible $text->thaw(); $hbox = new Gtk::HButtonBox(); $vbox->pack_start( $hbox, $false, $false, 0 ); $hbox->show(); # Create an editable check box $check = new Gtk::CheckButton( "Editable" ); $hbox->pack_start( $check, $false, $false, 0 ); $check->signal_connect( 'toggled', sub { $text->set_editable( $check->active ); } ); $check->set_active( $true ); $check->show(); # Create a word wrap check box $check = new Gtk::CheckButton( "Wrap Words" ); $hbox->pack_start( $check, $false, $true, 0 ); $check->signal_connect( 'toggled', sub { $text->set_word_wrap( $check->active ); } ); $check->set_active( $false ); $check->show(); $separator = new Gtk::HSeparator(); $main_vbox->pack_start( $separator, $false, $true, 0 ); $separator->show(); $vbox = new Gtk::VBox( $false, 10 ); $vbox->border_width( 10 ); $main_vbox->pack_start( $vbox, $false, $true, 0 ); $vbox->show(); # Create a close button $button = new Gtk::Button( "Close" ); $button->signal_connect( 'clicked', sub { Gtk->exit( 0 ); } ); $vbox->pack_start( $button, $true, $true, 0 ); $button->can_default( $true ); $button->grab_default(); $button->show(); $window->show(); main Gtk; exit( 0 ); # END EXAMPLE PROGRAM

Text Example Screenshot