martes, 18 de marzo de 2014

Python. Usando TreeStore. PyGtk


En esta 4 entrega, recordad una vez más de hacer un pull del repositorio, veremos como montar en la parte derecha de nuestra pantalla, las bases de datos de nuestro servidor, y dentro de cada base de datos, las tablas correspondientes y dentro , la estructura de cada uno de ellos.

Para usar la vista de arbol desde Glade, simplemente cogemos el objeto;

 self.view_tree = self.glade.get_object('treeview_tables')


Ahora, vamos a montar lo que habíamos comentado a través del método mount_treeview()

    def mount_treeview(self):
        pbd_bd = gtk.gdk.pixbuf_new_from_file("./images/bd.png")
        pbd_table = gtk.gdk.pixbuf_new_from_file("./images/table.png")
        pbd_field = gtk.gdk.pixbuf_new_from_file("./images/field.png")

He visto muchos ejemplos, en que la gente le da por cargar y guardar en el modelo de datos la imagen por cada fila. PITTTTT ERROR!!! INEFICAZ!
No hace falta, hombre. Se abre una sola vez, y se pasa esa imagen que será común a todas la filas. Eso significa , que si las imágenes pesan en memoria 30KB cada una, el consumo será, independientemente de las filas, 90K.
Si cargáramos por cada fila una imagen, pues multiplicar;
total memoria en imagen = filas * ( 3 * 30KB )

En fin, siempre viene bien recordad que la optimizaciones pequeñas, al final son las que marcan la diferencia entre un gran programa y un programa que se arrastra por el escritorio. ;-)

Vamos a ir comentando aunque el código habla por si solo.
Lo primero, es obtener las BD que tenemos en nuestro servidor de MySQL;


        #Preguntamos por la BDs
        sql = "Select schema_name From `INFORMATION_SCHEMA`.`SCHEMATA`"
        cursor = self.db.cursor()
        try:
            cursor.execute(sql)
            result_db = cursor.fetchall()
        except MySQLdb.Error, e:
            self.status_setText( "Error %d: %s" % (e.args[0], e.args[1]) )
            return

En la variable result_db, tenemos nuestras BD.
Ahora de lo que se trata es de empezar a rellenar nuestro TreeStore, que como vemos, estará formado por un tipo Pixbuf y un string;

        self.treestore = gtk.TreeStore(gtk.gdk.Pixbuf, str)

Ahora, lo que vamos hacer es recorrer nuestras bases de datos, y por cada una de ellos vamos a meterle las tablas. 

¿ Y como se hace ? pues a través de un iterator. 

Explicar que es un iterator me puede llevar bastante tiempo, así que vamos a suponer que tú eres un creyente, no importa de que religión o secta, la cuestión es que tienes que tener fe en lo que ves ;-)

Después, por ti mismo, busca documentación sobre ello, o ya reportaré alguna documentación que vi en su momento.

Bueno, como la fe en lo que ves, la introducción del primer grupo, en este caso las bases de datos, verás que el paso de parámetros es None, por la simple razón que es la raiz.

La llamada self.treestore.append nos devuelve un iterator a la vez que introduce el elemento de la base de datos y la imagen, [pbd_bd, bd[0]

Este indica el camino al padre.  ( Tú ves rezando ;-) )

        for bd in result_db:
            iter = self.treestore.append(None,[pbd_bd, bd[0]] )
            cursor1 = self.db.cursor()
            try:
                cursor1.execute( "show tables from " + bd[0])
                result_table = cursor1.fetchall()
            except MySQLdb.Error, e:
                self.status_setText( "Error %d: %s" % (e.args[0], e.args[1]) )
                return

Ahora, recorremos las tablas, que obtuvimos anteriormente con show tables from + la base de dato actual

Pero, ahora, a la hora de introducir en el TreeStore, vamos a indicar a que Padre, a través del iterator creado anteriormente, y que este, a su vez, nos devuelve otro iterator, iterchild, que lo usaremos posteriormente ;


            for table in result_table:
                iterchild = self.treestore.append(iter,[pbd_table, table[0] ] )
                cursor2 = self.db.cursor()
                try:
                  cursor2.execute( "show columns from " + bd[0] + "." + table[0])
                    result_field = cursor2.fetchall()
                except MySQLdb.Error, e:
                   self.status_setText( "Error %d: %s" % (e.args[0], e.args[1]) )
                   return

Bien, y para acabar, vamos a introducir la estructura en su tabla:

                for field in result_field:
                    self.treestore.append(iterchild,[pbd_field, field[0] ] )

Pues lo único que queda, es crear un par de columnas;

        #Create Columns from names fields
        column = gtk.TreeViewColumn( "", gtk.CellRendererPixbuf(), pixbuf=0)
        self.view_tree.append_column( column )
        column = gtk.TreeViewColumn( "Database", gtk.CellRendererText(), text=1 )
        self.view_tree.append_column( column )


Y asociar nuestro TreeStore a nuestra vista;
        self.view_tree.set_model( self.treestore )

El resultado, en la parte derecha de la imagen;



Ahora va tomando una forma más que elegante, para las pocas líneas que hemos picado ;-)

Os aseguro, que si no fuese por Glade, el picar hubiese sido muy tedioso.

En la próxima, veremos de incorporar una pequeña historia sobre las query que hemos ido realizando.

Ah, se me olvidaba, si pruebas USE BD_QUE_QUIERO, algo hace ;-)



GTXSII. Visual Basic .NET

Estamos trabajando muy duro en intentar en soportar más lenguajes de programación para nuestra librería GtxSII, para el Suministro Inmedi...