Editar texto con GTK y JavaScript
En el capítulo anterior del tutorial, ya viste como el usuario podía interactuar con tu aplicación. Eso si, las posibilidades de interacción eran básicas. Por el momento, tan solo podía pulsar botones. Eso si, botones que le permitían hasta elegir una tipografía concreta o un color. Sin embargo, esto no es suficiente. En ocasiones, necesitas que el usuario introduzca algo tan sencillo como su nombre. Para estos casos, para editar texto con Gtk, tienes a tu disposición dos clases muy interesantes como son Gtk.Entry y Gtk.TextView. Así, en este capítulo del tutorial te mostraré las opciones que puedes dar al usuario para editar texto.
Con estas dos clases, ya puedes crear formularios en cuadros de diálogo para que el usuario introduzca todo tipo de información y que pueda editar texto con GTK. Por supuesto, que no solo tienes estas dos, también tienes otras clases, combinación de algunas de las que has visto hasta el momento que te permiten introducir números mediante botones, como es Gtk.SpinButton.

Editar texto con GTK y JavaScript
Para poder ver la funcionalidad de cada una de las clases indicadas anteriormente, que te van a pertmitir editar texto con GTK, utilizaremos un sencillo ejemplo que, como siempre, puedes encontrar en el repositorio que existe para este tutorial.
En este caso, se trata de un cuadro de diálogo, con un par de botones de Aceptar y Cancelar, una etiqueta, donde se muestra lo que queremos que el usuario responda y la caja de texto, Gtk.Entry para que el usuario introduzca el valor.
En el caso de que el usuario pulse el botón aceptar, el valor que haya introducido en la caja de texto se imprimirá directamente en el log.
#!/usr/bin/env gjs
imports.gi.versions.Gtk = '3.0'
const {Gtk, GObject} = imports.gi;
Gtk.init(null);
var Dialog = GObject.registerClass(
class Dialog extends Gtk.Dialog{
_init(){
super._init({
defaultWidth:200,
defaultHeight: 200
});
let layout = new Gtk.Grid({
margin: 10,
rowSpacing: 5,
columnSpacing: 5
});
this.add_button("Aceptar", Gtk.ResponseType.OK);
this.add_button("Cancelar", Gtk.ResponseType.CANCEL);
this.get_content_area().add(layout);
layout.attach(new Gtk.Label({
label: "Nombre:"
}), 0, 0, 1, 1);
this.entry = new Gtk.Entry();
layout.attach(this.entry, 1, 0, 1, 1);
this.show_all();
}
}
);
let dialog = new Dialog();
if (dialog.run() == Gtk.ResponseType.OK){
log(dialog.entry.get_text());
}
La parte importante, la que te interesa, y sobre la que hay que trabajar es simplemente la que aparece this.entry = new Gtk.Entry(). Y, por supuesto, la parte donde se devuelve el contenido de la caja de texto, que al final es lo que realmente te interesa.
Gtk.Entry
En este apartado puedes encontrar, como de costumbre, algunas de las propiedades de esta clase. Básicamente, las que he considerado mas interesantes o relevantes. Por supuesto, también encontrarás de la misma forma alguno de los métodos exclusivos de la clase, como de las señales.
Propiedades
Lo primero es modificar el ejemplo anterior, en la parte en la que defines la caja de texto, reemplazando this.entry = new Gtk.Entry(), por el siguiente código, que mas adelante paso a desgranar,
this.entry = new Gtk.Entry({
text: "Lorenzo",
editable: true,
maxLength: 5,
visibility: true,
invisibleChar: "|",
widthChars: 55,
placeholderText: "Introduce tu nombre",
xalign: 0.5,
primaryIconTooltipText: "Borrar el contenido",
primaryIconStock: Gtk.STOCK_DELETE,
secondaryIconTooltipText: "Ayuda contextual",
secondaryIconStock: Gtk.STOCK_CLEAR
});
texteste propiedad se corresponde con el texto que se mostrará en el propio objeto.editableen el caso de serfalseel valor correspondiente a la propiedadtextno puede ser modificada por el usuario. Solo es posible editarla vía código.maxLengthes el número máximo de caracteres que admite la propiedadtext.visibilityesta propiedad es la que controla si el usuario ve exactamente lo que está escribiendo, o se muestra un carácter. Esta es la opción que tienes que utilizar para el caso de que quieras que el usuario introduzca una contraseña. Es posible cambiar el carácter que se muestra utilizando la propiedadinvisibleChar.widthCharste permite configurar el ancho del objetoGtk.Entryen número de caracteres.placeholderTextes el texto de ayuda que se muestra en la caja de texto, cuando no has introducido ningún valor, o no hay ningún valor por defecto. Normalmente se suele utilizar o bien un valor de ejemplo, o bien, se utiliza una ayuda. Si, por ejemplo, estás preguntando el nombre del usuario, elplaceholderTextpodría serintroduce aquí tu nombre.xalignte ayuda a controlar la posición del texto dentro delGkt.Entry, es decir, sería la alineación del texto. Se trata de un número real, con valor de0.0a1.0. El valor0.0se corresponde a que el texto se sitúa a la izquierda, mientras que un valor de1.0situaría el texto completamente a la derecha. Si lo que quieres es que el texto aparezca centrado, tienes que utilizar0.5, como seguramente ya te habrás imaginado.primaryIconStock, esta propiedad controla el icono que aparece en la parte izquierda de la caja de texto. Normalmente este icono se utiliza para desencadenar determinadas acciones.primaryIconTooltipTexteste es un texto de ayuda que se muestra cuando sitúas el ratón sobre elprimaryIcon.secondaryIconStockes exactamente igual que elprimaryIconStock, pero es el que gestiona el icono que se sitúa en la parte derecha de la caja de texto.secondaryIconTooltipTextesta propiedad se encarga de mostrar la ayuda cuando sitúas el ratón sobre elsecondaryIcon.
Métodos
Por supuesto los dos métodos por excelencia para un objeto de esta clase Gtk.Entry, son sin lugar a dudas, get_text y set_text, que te permiten obtener y establecer el texto del Gtk.Entry.
Señales
Dentro de las señales que te pueden resultar interesantes, para modificar el comportamiento de un objeto de la clase Gtk.Entry, tienes
activatese produce cuando el usuario pulsa la teclaEnterbackspaceexactamente igual que la anterior pero para el caso para la teclaborrarcopy-clipboard,cut-clipboardypaste-clipboardcontrolan la interacción con el portapapeles, cuando se copia, se corta o se pega del portapapeles respectivamente.
Gtk.TextView
Esta clase te va a permitir crear objetos para introducir texto, pero donde vas a tener mucho mas control sobre que es lo que se introduce y como se introduce. En este caso, he modificado el ejemplo anterior, como te muestro a continuación,
this.entry = new Gtk.TextView({
buffer: new Gtk.TextBuffer({
text: "Este es un texto mas largo"
}),
editable: true,
justification: Gtk.Justification.CENTER,
leftMargin: 10,
rightMargin: 10,
pixelsAboveLines: 10,
pixelsBelowLines: 10
});
Propiedades
Sin lugar a dudas, la propiedad mas importante de todas las anteriores es buffer que es la que gestiona y control el texto dentro de un Gtk.TextView. El resto de propiedades, algunas de las que he puesto en el ejemplo anterior, son de menor importancia, y tienen mas que ver como se muestra el texto dentro de un Gtk.TextView. Así tienes,
editablepara definir si el contenido es modificable o no.justificationte permite establecer donde se alinea el texto, a la derecha, a la izquierda o centradoleftMarginyrightMarginte ayuda a establecer el espacio en pixel que dejas a izquierda y derecha respectivamente.pixelsAboveLinesypixelsBelowLinesdefinen los pixel que dejas por la parte superior y por la parte inferior de un párrafo.
Métodos
De nuevo de entre los métodos que tiene la clase Gtk.TextView los que destaca son los referentes a conseguir el buffer, que son básicamente get_buffer y set_buffer. Pero también tiene otros interesantes, como
scroll_to_iterque permite desplazar el scroll hasta una posición definida por unGtk.TextIterscroll_to_markigual que el caso anterior pero para unGtk.TextMarkget_iter_locationdevuelve un rectángulo que delimita el carácter que se encuentra en la posiciónGtk.TextIter.get_iter_at_locationdevuelve elGtk.TextIterque se encuentra en unas coordenads determinadas dentro del texto.
Señales
Un objeto de la clase Gtk.TextView tiene algunas señales similares a las de Gtk.TextEntry, como pueden ser las relativas al portapapeles, y otras específicas como move-cursor, mov-focus, move-viewport.
Gtk.TextBuffer
Esta clase es la encargada de guardar y gestionar el texto que se muestra en un Gtk.TextView.
Propiedades
De entre las propiedades de esta clase, cabe destacar dos principalmente,
text, básicamente el contenido de unGtk.TextBuffer.cursorPositionque indica la posición del cursor y es de solo lectura.
Métodos
La clase Gtk.TextBuffer tiene una gran cantidad de métodos que te permiten gestionar perfectamente el texto que contiene. Sin embargo, hay algunos de ellos, que son imprescindibles hasta para lo más básico, como es el simple hecho de obtener el texto que contiene el objeto.
Además de la clase Gtk.TextBuffer, tienes que tener presente una clase mas como es Gtk.TextIter. Esta clase apunta una ubicación dentro de la clase Gtk.TextBuffer. Por ejemplo, si quieres obtener el inicio del Gtk.TextBuffer tienes que utilizar el método get_start_iter, mientras que si quieres obtener el final, tendrías que utilizar el método get_end_iter. De esta forma para obtener el texto contenido en un Gtk.TextBuffer, tienes que utilizar algo como lo que te muestro a continuación,
let buffer = dialog.entry.get_buffer();
let inicio = buffer.get_start_iter();
let fin = buffer.get_end_iter();
print(buffer.get_text(inicio, fin, false));
Esto que parece algo engorroso, lo cierto es que te da muchas opciones y posibilidades, dado que Gtk.TextBuffer pone a tu alcance diferentes herramientas y clases como son las marcas Gtk.TextMark que se conservan a pesar de las modificaciones que se produzcan. También tienes las etiquetas Gtk.TextTag, que te permiten aplicar atributos al texto.
Así algunas de las herramientas que puedes utilizar con Gtk.TextBuffer, además de la que te he comentado para extraer el texto son,
deletete permite borrar texto entre dosGtk.TextIterinsertpara insertar texto en unGtk.TextIterinsert_at_cursorigual que el anterior, pero en este caso insertará el texto en la posición del cursor.
Además puedes realizar diferentes operaciones relacionadas con el portapapeles, como
copy_clipboardpara copiar al portapapelescut_clipboarden el caso de que quieras cortarpaste_clipboardpara pegar desde el portapapeles en la posición indicada por unGtk.TextIter.
Señales
Por supuesto que Gtk.TextBuffer viene cargado de señales que te van a facilitar la interacción con este objeto. De las mas interesantes, por supuesto, es changed que te informa cuando se ha producido un cambio en el contenido. Por ejemplo, si quieres ver el contenido cada vez que se produce un cambio puedes utilizar el siguiente código,
this.buffer.connect('changed', (tb)=>{
let inicio = tb.get_start_iter();
let fin = tb.get_end_iter();
print(tb.get_text(inicio, fin, false));
});
Pero, por supuesto tienes otras señales como apply-tag, insert-text, insert-pixbuf, mark-deleted, mark-set, paste-done.
Conclusiones
Ya has visto algunas de las opciones que puedes ofrecer a un usuario para introducir y editar texto con GTK y JavaScript, en tus aplicaciones. Desde la solución mas sencilla, que te ofrece Gtk.Entry a una algo mas compleja como es Gtk.TextView.
Estas, no son las únicas, pero son las que utilizarás, en principio, con mas frecuencia.
Imagen de portada de Michelle Miralles en Unsplash
La entrada Editar texto con GTK y JavaScript aparece primero en Atareao.
