Widgets nativos en JavaScript

Aplicaciones nativas en JavaScript con GJSAplicaciones nativas en JavaScript con GJS

Este es uno de los capítulos del tutorial Aplicaciones nativas en JavaScript con GJS. Encontrarás los enlaces a todos los de capítulos, al final de este artículo.

En el capítulo de introducción di paso entre otras conceptos, a los widgets. En este capítulo entraré a detallar las diferentes características de los widgets. Al fin y al cabo, son la pieza fundamental con la que desarrollar tus aplicaciones.

Los widgets son una pieza básica dentro del desarrollo de interfaces gráficas en el ecosistema GTK+. Tienen una serie de características y propiedades que hacen que sea necesario un estudio pormenorizado. Un estudio pormenorizado, no solo del concepto widget, con todas sus generalidades, sino también, de cada uno de los widgets, que actualmente están al alcance de tus manos.

Y es que como verás de aquí en adelante, hay widgets de todo tipo, y para cada una de las necesidades que te puedas imaginar. Así, tienes widgets para mostrar texto, o introducir texto, para mostrar progreso, barras de desplazamiento, y mucho mas.

Widgets nativos en JavaScript

Widgets nativos en JavaScript

Como decía en la introducción de este tutorial, un widget, no es mas que una parte de tu aplicación con la que el usuario puede interactuar. En este sentido, y como cualquier otro objeto, un widget, tiene métodos y propiedades. Pero no solo, esto, dado que como indiqué anteriormente, son objetos orientados a eventos.

Eventos

Un widget es susceptible a eventos. Pero, ¿que es un evento?. Por ejemplo, cuando haces clic sobre un botón, esto es un evento. Pero no solo esto, cuando pasas el ratón por encima del mismo botón, o cuando pulsas una tecla… Todo esto son eventos, que te van a permitir interaccionar con el widget en cuestión.

El objeto está siempre escuchando a la espera de que se produzca un evento, para en ese caso realizar algún tipo de acción.

Ahora bien, es necesario, indicar al widget las acciones que debe acometer cuando se produce un evento. Es decir, que aunque el widget esté a la escucha, éste no hará nada, a menos que le indiquemos que es lo que tiene que hacer. En el siguiente ejemplo, conectamos el evento de hacer click con una acción, en este caso escribir en el log.

button.connect('clicked', ()=>{
    log('Alguien pulsó el botón');
});

En este caso,

  • widget => button
  • evento => clicked
  • acción => log('Alguien pulsó el botón')

Un ejemplo

Para que asentar los conceptos, lo mejor es verlo en un ejemplo, para que te hagas una idea de quien es quien. En este ejemplo, aparecen conceptos que verás en siguientes capítulos del tutorial. Sin embargo, creo que es interesante que puedes comenzar a jugar con gjs y Gtk, para que puedas empezar a disfrutar y le puedas sacar todo el partido posible.

Utilizaré este mismo ejemplo a lo largo de los diferentes capítulos del tutorial. Evidentemente, con el paso de los mismos, se irá completando con nuevos widgets y otros elementos.

#!/usr/bin/env gjs

imports.gi.versions.Gtk = '3.0'
const {Gtk, GObject} = imports.gi;

Gtk.init(null);

var Ventana = GObject.registerClass(
    class Ventana extends Gtk.Window{
        _init(){
            super._init({
                defaultWidth:200,
                defaultHeight: 200
            });
            let boton = new Gtk.Button({label: 'Para salir'});
            boton.connect('clicked', () => {
                print('Adios');
                Gtk.main_quit();
            });
            this.add(boton);
        }
    }
);

let ventana = new Ventana();
ventana.show_all();

Gtk.main();

Copia el código anterior, y lo pegas en un archivo, ejemplo.js. Para ejecutarlo, simplemente tienes que utilizar la siguiente instrucción, gjs ejemplo.js. A partir de aquí, ya puedes comenzar a jugar con él.

Revisando el ejemplo

No voy a entrar en ver cada uno de los objetos y detalles del ejemplo anterior, esto lo dejo para posteriores capítulos de este tutorial. El objetivo en este caso, es dejar claro, el concepto de widgets, eventos y acciones.

En este primer ejemplo, utilizas dos widgets, el widget Gtk.Window y el Gtk.Button. En el primer caso, lo he redifinido, creando un nuevo widget, denominado Ventana, con algunas características nuevas, como, es por ejemplo el botón.

En el caso del botón, le hemos definido una propiedad, como es la etiqueta, y lo hemos hecho en la propia declaración del botón,

let boton = new Gtk.Button({label: 'Para salir'});

Por otro lado, has conectado el evento, clicked con una acción. Esto lo haces con las siguientes líneas,

boton.connect('clicked', () => {
    print('Adios');
    Gtk.main_quit();
});

En concreto, cuando hagas clic en el botón, vas a imprimir la palabra Adios, y saldrás de la ventana.

Probando mas widgets y acciones

Para asentar los pocos conceptos que has visto hasta el momento, completemos el ejemplo anterior introduciendo dos nuevos widget, Gtk.MessageDialog. Este nuevo widget te va permitir mostrar un cuadro de diálogo para interactuar con el usuario.

El otro widget que he introducido es Gtk.Grid. Este elemento, es un layout, que te permite disponer varios objetos o widget en su interior. Y es que Gtk.Window, solo te permite añadir un wiget, con el método this.add. Así que la solución, como verás en las siguientes líneas es añadir este Gtk.Grid, y en su interior, disponer tantos widgets, como necesites

El objetivo, no es esplicarte como funciona cada uno de estos widgets, simplemente es conocer, lo que son los eventos y las acciones. En capítulos posteriores verás los diferentes layout que tienes a tu disposición y como se utilizan.

#!/usr/bin/env gjs

imports.gi.versions.Gtk = '3.0'
const {Gtk, GObject} = imports.gi;

Gtk.init(null);

var Ventana = GObject.registerClass(
    class Ventana extends Gtk.Window{
        _init(){
            super._init({
                defaultWidth:200,
                defaultHeight: 200
            });
            this.connect('destroy', ()=>{
                Gtk.main_quit();
            });
            let layout = new Gtk.Grid();
            this.add(layout);
            let button = new Gtk.Button({label: 'Dialogo'});
            button.connect('clicked', () => {
                let dialog = new Gtk.MessageDialog({
                    title: 'Ejemplo',
                    text: 'Ejemplo de diálogo'
                });
                dialog.add_button('Si', Gtk.ResponseType.YES);
                dialog.run();
                dialog.destroy();
            });
            layout.attach(button, 0, 0, 1, 1);
            let button2 = new Gtk.Button({label: 'Para salir'});
            button2.connect('clicked', () => {
                print('Adios');
                Gtk.main_quit();
            });
            layout.attach(button2, 0, 1, 1, 1);
        }
    }
);

let ventana = new Ventana();
ventana.show_all();

Gtk.main();

Como ves he añadido un segundo botón, en realidad un primer botón, que te muestra un objeto del tipo Gtk.MessageDialog. A este objeto le hemos añadido un botón con sus propias características, y nos aseguramos de que al salir, se destruye el diálogo.

Por otro lado, si te fijas al inicio hemos añadido una nueva acción que responde a un nuevo evento. En concreto es lo siguiente,

this.connect('destroy', ()=>{
    Gtk.main_quit();
});

En el primer ejemplo, si cierras la ventana desde el botón propio de la ventana, el que se situa en la parte superior derecha del encabezado de la misma, verás que la ventana, efectivamente se cierra, pero no salimos de la aplicación. Para conseguir esto, tienes que asignar al evento destroy, la acción Gtk.main_quit(). Esta el la misma acción que asignaste al button2, con el evento clicked.

Conclusión

Espero que con estos ejemplos haya quedado suficientemente explicado los diferentes conceptos de widget, evento y acción. Pero no solo esto, también espero, que hayas podido empezar a jugar con el código, y los diferentes widget, que al final de eso se trata también, claro.


Imagen de portada de Brett Jordan en Unsplash

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *