13.2. Vistas de Texto

Sólo hay una función para crear un control TextView (Vista de Texto).

  textview = gtk.TextView(buffer=None)

Cuando se crea una TextView también se creará un TextBuffer (Buffer de Texto) asociado y una TextTagTable (Tabla de Etiquetas de Texto) de forma predeterminada. Si quieres usar un TextBuffer ya existente puedes especificarlo en el método anterior. Para cambiar el TextBuffer que usa una TextView usa el siguiente método:

  textview.set_buffer(buffer)

Usa el siguiente método para obtener una referencia al TextBuffer a partir de una TextView:

  buffer = textview.get_buffer()

Un control de TextView no tiene barras de desplazamiento para ajustar la vista en caso de que el texto sea más grande que la ventana. Para incluir barras de desplazamiento, tienes que añadir la TextView a una ScrolledWindow (Ventana de Desplazamiento).

Una TextView se puede usar para permitir al usuario editar un cuerpo de texto, o para visualizar varias lineas de un texto de sólo lectura para el usuario. Para cambiar entre estos modos de operación, utiliza el siguiente método:

  textview.set_editable(valor)

El argumento valor puede ser TRUE o FALSE y especifica si el usuario puede editar el contenido del control TextView . El modo de edición de la TextView puede cambiarse en rangos de texto dentro del TextBuffer usando TextTags.

Puedes obtener el modo actual de edición usando el método:

  setting = textview.get_editable()

Cuando la TextView no es editable probablemente deberías ocultar el cursor usando el método:

  textview.set_cursor_visible(valor)

El argumento valor puede ser TRUE o FALSE y especifica si el cursor debe ser visible. La TextView puede ajustar las lineas de texto que son demasiado largas para que quepan en una única linea de la ventana. El comportamiento predeterminado es no ajustar las lineas. Esto se puede cambiar usando el método:

  textview.set_wrap_mode(wrap_mode)

Este método te permite especificar que el texto debe ajustarse en los límites de palabras o caracteres. El argumento word_wrap puede ser:

  gtk.WRAP_NONE # sin ajuste
  gtk.WRAP_CHAR # ajuste por caracteres
  gtk.WRAP_WORD # ajuste por palabras

La justificación predetermianda del texto en una TextView se puede fijar y obtener usando los métodos:

  textview.set_justification(justification)
  justification = textview.get_justification()

donde justification puede ser:

  gtk.JUSTIFY_LEFT   # justificación a la izquierda
  gtk.JUSTIFY_RIGHT  # justificación a la derecha
  gtk.JUSTIFY_CENTER # justificación al centro

Nota

La justificación será JUSTIFY_LEFT si el modo de ajuste es WRAP_NONE. Las etiquetas asociadas con un TextBuffer pueden cambiar la justificación predeterminada.

Se pueden modificar y ver otros atributos predeterminados en una TextView como el margen izquierdo, el margen derecho, las tabulaciones y la indentación de párrafos, usando los siguientes métodos:

  # margen izquierdo
  textview.set_left_margin(left_margin)
  left_margin = textview.get_left_margin()
  
  # margen derecho
  textview.set_right_margin(right_margin)
  right_margin = textview.get_right_margin()
  
  # indentación
  textview.set_indent(indent)
  indent = textview.get_indent()
  
  textview.set_pixels_above_lines(pixels_above_line)
  pixels_above_line = textview.get_pixels_above_lines()
  
  textview.set_pixels_below_lines(pixels_below_line)
  pixels_below_line = textview.get_pixels_below_lines()
  
  textview.set_pixels_inside_wrap(pixels_inside_wrap)
  pixels_inside_wrap = textview.get_pixels_inside_wrap()

  # tabulaciones  
  textview.set_tabs(tabs)
  tabs = textview.get_tabs()

left_margin, right_margin, indent, pixels_above_lines, pixels_below_lines y pixels_inside_wrap se especifican en píxeles. Los valores predeterminados de estos parámetros se pueden modificar con etiquetas asociadas a un TextBuffer. tabs es un pango.TabArray.

El programa de ejemplo textview-basic.py ilustra el uso básico del control TextView:

Figura 13.1. Ejemplo básico de Vista de Texto

Ejemplo básico de Vista de Texto

El código fuente del programa es:

    1	#!/usr/bin/env python
    2	
    3	# example textview-basic.py
    4	
    5	import gtk
    6	
    7	class TextViewExample:
    8	    def toggle_editable(self, checkbutton, textview):
    9	        textview.set_editable(checkbutton.get_active())
   10	
   11	    def toggle_cursor_visible(self, checkbutton, textview):
   12	        textview.set_cursor_visible(checkbutton.get_active())
   13	
   14	    def toggle_left_margin(self, checkbutton, textview):
   15	        if checkbutton.get_active():
   16	            textview.set_left_margin(50)
   17	        else:
   18	            textview.set_left_margin(0)
   19	
   20	    def toggle_right_margin(self, checkbutton, textview):
   21	        if checkbutton.get_active():
   22	            textview.set_right_margin(50)
   23	        else:
   24	            textview.set_right_margin(0)
   25	
   26	    def new_wrap_mode(self, radiobutton, textview, val):
   27	        if radiobutton.get_active():
   28	            textview.set_wrap_mode(val)
   29	
   30	    def new_justification(self, radiobutton, textview, val):
   31	        if radiobutton.get_active():
   32	            textview.set_justification(val)
   33	
   34	    def close_application(self, widget):
   35	        gtk.mainquit()
   36	
   37	    def __init__(self):
   38	        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
   39	        window.set_resizable(gtk.TRUE)  
   40	        window.connect("destroy", self.close_application)
   41	        window.set_title("TextView Widget Basic Example")
   42	        window.set_border_width(0)
   43	
   44	        box1 = gtk.VBox(gtk.FALSE, 0)
   45	        window.add(box1)
   46	        box1.show()
   47	
   48	        box2 = gtk.VBox(gtk.FALSE, 10)
   49	        box2.set_border_width(10)
   50	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
   51	        box2.show()
   52	
   53	        sw = gtk.ScrolledWindow()
   54	        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
   55	        textview = gtk.TextView()
   56	        textbuffer = textview.get_buffer()
   57	        sw.add(textview)
   58	        sw.show()
   59	        textview.show()
   60	
   61	        box2.pack_start(sw)
   62	        # Load the file textview-basic.py into the text window
   63	        infile = open("textview-basic.py", "r")
   64	
   65	        if infile:
   66	            string = infile.read()
   67	            infile.close()
   68	            textbuffer.set_text(string)
   69	
   70	        hbox = gtk.HButtonBox()
   71	        box2.pack_start(hbox, gtk.FALSE, gtk.FALSE, 0)
   72	        hbox.show()
   73	
   74	        vbox = gtk.VBox()
   75	        vbox.show()
   76	        hbox.pack_start(vbox, gtk.FALSE, gtk.FALSE, 0)
   77	        # check button to toggle editable mode
   78	        check = gtk.CheckButton("Editable")
   79	        vbox.pack_start(check, gtk.FALSE, gtk.FALSE, 0)
   80	        check.connect("toggled", self.toggle_editable, textview)
   81	        check.set_active(gtk.TRUE)
   82	        check.show()
   83	        # check button to toggle cursor visiblity
   84	        check = gtk.CheckButton("Cursor Visible")
   85	        vbox.pack_start(check, gtk.FALSE, gtk.FALSE, 0)
   86	        check.connect("toggled", self.toggle_cursor_visible, textview)
   87	        check.set_active(gtk.TRUE)
   88	        check.show()
   89	        # check button to toggle left margin
   90	        check = gtk.CheckButton("Left Margin")
   91	        vbox.pack_start(check, gtk.FALSE, gtk.FALSE, 0)
   92	        check.connect("toggled", self.toggle_left_margin, textview)
   93	        check.set_active(gtk.FALSE)
   94	        check.show()
   95	        # check button to toggle right margin
   96	        check = gtk.CheckButton("Right Margin")
   97	        vbox.pack_start(check, gtk.FALSE, gtk.FALSE, 0)
   98	        check.connect("toggled", self.toggle_right_margin, textview)
   99	        check.set_active(gtk.FALSE)
  100	        check.show()
  101	        # radio buttons to specify wrap mode
  102	        vbox = gtk.VBox()
  103	        vbox.show()
  104	        hbox.pack_start(vbox, gtk.FALSE, gtk.FALSE, 0)
  105	        radio = gtk.RadioButton(None, "WRAP__NONE")
  106	        vbox.pack_start(radio, gtk.FALSE, gtk.TRUE, 0)
  107	        radio.connect("toggled", self.new_wrap_mode, textview, gtk.WRAP_NONE)
  108	        radio.set_active(gtk.TRUE)
  109	        radio.show()
  110	        radio = gtk.RadioButton(radio, "WRAP__CHAR")
  111	        vbox.pack_start(radio, gtk.FALSE, gtk.TRUE, 0)
  112	        radio.connect("toggled", self.new_wrap_mode, textview, gtk.WRAP_CHAR)
  113	        radio.show()
  114	        radio = gtk.RadioButton(radio, "WRAP__WORD")
  115	        vbox.pack_start(radio, gtk.FALSE, gtk.TRUE, 0)
  116	        radio.connect("toggled", self.new_wrap_mode, textview, gtk.WRAP_WORD)
  117	        radio.show()
  118	
  119	        # radio buttons to specify justification
  120	        vbox = gtk.VBox()
  121	        vbox.show()
  122	        hbox.pack_start(vbox, gtk.FALSE, gtk.FALSE, 0)
  123	        radio = gtk.RadioButton(None, "JUSTIFY__LEFT")
  124	        vbox.pack_start(radio, gtk.FALSE, gtk.TRUE, 0)
  125	        radio.connect("toggled", self.new_justification, textview,
  126	                      gtk.JUSTIFY_LEFT)
  127	        radio.set_active(gtk.TRUE)
  128	        radio.show()
  129	        radio = gtk.RadioButton(radio, "JUSTIFY__RIGHT")
  130	        vbox.pack_start(radio, gtk.FALSE, gtk.TRUE, 0)
  131	        radio.connect("toggled", self.new_justification, textview,
  132	                      gtk.JUSTIFY_RIGHT)
  133	        radio.show()
  134	        radio = gtk.RadioButton(radio, "JUSTIFY__CENTER")
  135	        vbox.pack_start(radio, gtk.FALSE, gtk.TRUE, 0)
  136	        radio.connect("toggled", self.new_justification, textview,
  137	                      gtk.JUSTIFY_CENTER)
  138	        radio.show()
  139	
  140	        separator = gtk.HSeparator()
  141	        box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 0)
  142	        separator.show()
  143	
  144	        box2 = gtk.VBox(gtk.FALSE, 10)
  145	        box2.set_border_width(10)
  146	        box1.pack_start(box2, gtk.FALSE, gtk.TRUE, 0)
  147	        box2.show()
  148	
  149	        button = gtk.Button("close")
  150	        button.connect("clicked", self.close_application)
  151	        box2.pack_start(button, gtk.TRUE, gtk.TRUE, 0)
  152	        button.set_flags(gtk.CAN_DEFAULT)
  153	        button.grab_default()
  154	        button.show()
  155	        window.show()
  156	
  157	def main():
  158	    gtk.main()
  159	    return 0
  160	
  161	if __name__ == "__main__":
  162	    TextViewExample()
  163	    main()

Las lineas 8-32 definen las retrollamadas para los botones de exclusión mútua y los botones de activación que se usan para cambiar los atributos predeterminados de la TextView. Las lineas 53-61 crean una ScrolledWindow para contener la TextView. La ScrolledWindow se coloca en una VBox con los botones que se crean en las lineas 70-138. El TextBuffer asociado con la TextView se rellena con el contenido del archivo fuente en las lineas 62-68.