domingo, 9 de marzo de 2014

Maneras de hacer en PyGTK( Python ) vs T-GTK ( Harbour )


El haber usado Glade para el diseño del GUI para mi programa de Maquinas-Herramientas, me ha va permitir aprender Python con PyGtk, muchos más rápido, porque las pantallas ya las tengo creadas.

De esta manera, todo el interface es reusable 100%.

Siempre he pensado que aprender un nuevo lenguaje haciendo simples funciones que muestran como hacer el factorial de un número es súper aburrido.

¿ A quién le resulta divertido "ver", de hecho no vas a ver un carajo, como funciona una función recursiva? ¿ De verdad te vas a sentir realizado viendo un puñado de números sin sentido ? ;-)

Por eso, voy a intentar portar mi programa a Python para aprender de él, y de paso, ver como evoluciona, y sentirme satisfecho de ver ventanas, botones, carga de datos en una vista, etc..

¿ A que suena mejor ? Como no, comparar un triste número en un interprete a ver una ventana que responde a tus acciones no tiene color ;-)

Esta es el código de la ventana de Login usando T-GTK


    SET RESOURCES pGlade FROM FILE "./gui/pol.ui"

    DEFINE WINDOW oWnd ID "inicio" RESOURCE pGlade

            DEFINE ENTRY VAR s_cUser      ID "entry_user"     RESOURCE pGlade
            DEFINE ENTRY VAR s_cPass      ID "entry_pass"     RESOURCE pGlade
            DEFINE ENTRY VAR s_cServer    ID "entry_server"   RESOURCE pGlade
            DEFINE SPIN  VAR s_nPort      ID "spin_port"      RESOURCE pGlade
            DEFINE ENTRY VAR s_cDBName    ID "entry_bd"       RESOURCE pGlade
            DEFINE LABEL oLabelInf        ID "information"    RESOURCE pGlade

            DEFINE BUTTON oBtn ID "btn_access" RESOURCE pGlade;
                          ACTION ( oBtn:Disable(),;
                                   IF( !empty( oServer := Connect_Db( oLabelInf )),( oWnd:End() ), ),;
                                   oBtn:Enable() )

            DEFINE BUTTON ID "btn_cancel" RESOURCE pGlade ACTION ( oWnd:End() )

    ACTIVATE WINDOW oWnd INITIATE


En PyGTK;

__author__ = 'rafa'

import pygtk
pygtk.require('2.0')
import gtk
import MySQLdb
import os

class Login:

    def __init__(self):

        """
        Ventana de acceso a la BD
        """

        self.conectado = False

        self.gladefile = "./gui/pol.ui"
        self.glade = gtk.Builder()
        self.glade.add_from_file(self.gladefile)

        #accediendo a los controles
        self.window = self.glade.get_object('inicio')
        self.window.connect("destroy", self.destroy)

        self.btn_access = self.glade.get_object('btn_access')

        # este salta a un method
        self.btn_access.connect("clicked", self.Conect_Db, None)

        self.btn_cancel = self.glade.get_object('btn_cancel')
        self.btn_cancel.connect("clicked", self.destroy )

        self.label = self.glade.get_object('information')

        self.entry_user   = self.glade.get_object('entry_user')
        self.entry_user.connect("key-press-event", self.on_key_press_event )

        self.entry_pass   = self.glade.get_object('entry_pass')
        self.entry_pass.connect("key-press-event", self.on_key_press_event )

        self.entry_server = self.glade.get_object('entry_server')
        self.entry_bd     = self.glade.get_object('entry_bd')
        self.spin_port    = self.glade.get_object('spin_port')

    def on_key_press_event(self, widget, event):
        keyname = gtk.gdk.keyval_name(event.keyval)

        if keyname == "Return" or keyname == "KP_Enter":
            widget.get_toplevel().child_focus(gtk.DIR_TAB_FORWARD)

    # Cuando destruimos la pantalla, si no estamos conectado, salimos de la aplicacion.
    def destroy(self, widget, data=None):
        if not self.conectado:
            gtk.main_quit()
            os.sys.exit (1)
        else:
            gtk.main_quit()

    def main(self):
        gtk.main()

        return 0

En parte , la ventaja de T-GTK, en este caso es de Harbour y su maravilloso Preprocesado , que nos permite crear comandos, "ocultando " el uso de clases, aunque por debajo, el trabajo realizado es similar a la librería de PyGtk.

Pero, he aquí donde la potencia de Glade:

        SET RESOURCES pGlade FROM FILE "./gui/pol.ui"
        DEFINE WINDOW oWnd ID "inicio" RESOURCE pGlade

en PyGtk;

        self.gladefile = "./gui/pol.ui"
        self.glade = gtk.Builder()
        self.glade.add_from_file(self.gladefile)

        #accediendo a los controles
        self.window = self.glade.get_object('inicio')
        self.window.connect("destroy", self.destroy)

En Harbour escribimos muchísimo menos para obtener lo mismo, gracias a su potente preprocesado.
Pero lo importante, es que convertir un programa en otro a través de Glade, es de una gran ayuda.

O por decirlo de otra manera, un diseñador puede hacer las pantallas, mientras el programador lo dota de funcionalidad.

Esta manera , la de separar GUI y funcionalidad, me encanta. ;-)


Android y Git. Disponer del hash automáticamente.

Una de las cosas a las que estoy acostumbrado, es tener siempre en mi código, el hash/tag/versión del control de versiones que estoy usan...