11 may. 2011

GtkBuilder y Python Parte 5

Si estas leyendo esta entrada quizás te interesaría revisar las anteriores.

Esta entrada quizás es la mas relevante para el buen funcionamiento del programa, hasta este punto hemos configurado los diálogos de abrir y seleccionar carpeta. Por suerte para nosotros Python ha creado módulos que hacen el trabajo bastante simple, lo que vamos a configurar es quizas una de las características más difíciles de trabajar cuando se hace en Pygtk, me estoy refiriendo al Gtk.Treeview que es sin duda alguna una pesadilla, pero les voy a mostrar de forma fácil como trabajar esto.

Gracias a Glade ya nosotros creamos un modelo que se llama MediaList y otro que se llama OrderList los TreeView básicamente permiten construir modelos dentro de ellos, esto suele ser un tema altamente complejo porque en Pygtk es un monstruo esto.

Nosotros contamos con la suerte de haber creado un Gtk.Liststore y asociarlo a un Gtk.Treeview y a su vez dentro del Liststore hemos creado dos gchararray, si yo se que suena todo de una forma miedoso pero todo eso lo hicimos en glade en el tutorial 3 sin necesidad de crear todo una cadena de códigos en Pygtk.
Hemos reducido todo este texto a una sola linea y nos hemos ahorrado usar Pygtk que es una tecnología que ya no se esta usando y permanecemos con tecnología moderna como Gtk 3 y Gtk 2 dentro de GtkBuilder

self.medialist = builder.get_object("MediaList")

Esta linea que esta en roja va justo donde hemos llamado los GtkBuilders quedando ubicada como la linea numero 9 de nuestro codigo.

def __init__(self): # Crea la ventana de trabajo Principal y obtiene los objetos en Glade builder = Gtk.Builder() builder.add_from_file("Multiplay.ui") self.addfile = builder.get_object("Add") self.addfolder = builder.get_object("AddFolder") self.save = builder.get_object("Save") self.about = builder.get_object("About") self.medialist = builder.get_object("MediaList") self.filterbox = Gtk.FileFilter()



Ya se que aun no entienden que hemos logrado, pero les voy a dar el ejemplo más claro, vamos a terminar de configurar definitivamente los dialogos de Abrir y Seleccionar Carpeta y vamos a mostrar cada uno de los archivos que seleccionemos dentro del programa en el Gtk.Treeview.

Para ello tenemos que importar un modulo que trabaja con archivos y permitirá ahorrar mucho trabajo, este modulo es usado para todo lo relacionado con archivos, cosas como abrir, ver rutas, guardar y demás, la belleza de python reside en que existe muchos módulos que hacen la vida tan simple.

import os


Esta linea la ponemos antes de from gi.repository import Gtk


Ahora debemos recordar la definición del comando Agregar, como pueden notar ahora las lineas 14, 15 y 16 han sido agregadas, la linea 14 lo que hace es iterar con todos los nombres de archivos seleccionados, recuerden que en la linea 13 usamos get_filenames() que obtiene todos los nombres de archivos seleccionados en oposición a get_filename() que solo obtiene el nombre de un archivo seleccionado. La linea 15 va a crear una tupla con dos columnas, la primera contendrá las direcciones y la segunda contendrá el nombre de los archivo, la función os.path.split(files) es una función que divide en dos columnas el nombre de un archivo de la siguiente forma.

Ejemplo:
Seleccionamos el archivo siguiente:
/home/geojorg/Música/Aerosmith/Aerosmith - Just Push Play.mp3
Al aplicar os.path.split a la dirección anterior nos mostrara lo siguiente.("/home/geojorg/Música/Aerosmith/" , "Aerosmith - Just Push Play.mp3")
Como pueden ver creo una tupla con dos columnas, en la primera esta la ruta del archivo y en la segunda el nombre del archivo.

#Definicion del comando Agregar def showAddFile(self, widget): self.filterbox.set_name("Media Files") for name, pattern in filepattern: self.filterbox.add_pattern(pattern) self.addfile.add_filter(self.filterbox) respt = self.addfile.run() self.addfile.remove_filter(self.filterbox) self.addfile.hide() if respt == -5: fileselected = self.addfile.get_filenames() for files in fileselected: (dirs,files)= os.path.split(files) self.medialist.append([files,dirs])


Ahora que hemos creado la tupla con la linea 15 lo ideal es es que la linea 16 agregue estos dos elementos a nuestro Gtk.Treeview, lo agregara de la siguiente forma, la primera columna es la 0 y esa columna contendrá los nombres del archivo, en nuestro ejemplo seria Aerosmith - Just Push Play.mp3 y la columna 1 no es visible pero en ella guardara la Ruta /home/geojorg/Música/Aerosmith/ se preguntaran porque esto. Les debo decir que la respuesta esta en el tutorial 2, se acuerdan que pusimos un valor de 0 al crear el TextView, bueno eso básicamente hace que solo se pueda ver la columna 0 y esa es la idea.

Ahora en la definición de Seleccionar Carpeta vamos a hacer unos cambios también. Hemos agregado la linea 16, 17 y 18. Vamos a explicar entonces.
La linea 16 va iterar en la carpeta seleccionada con la linea 14, para carpetas siempre usamos get_filename() porque solo vamos a seleccionar una y de ahí seleccionamos todas la hijas que estén dentro de esta, se puede lograr esto usando el comando os.walk que es un comando que funciona de forma iterativa y recursiva hacia abajo. Para que quede un poco mas claro vamos a hacer un ejemplo.


Ejemplo:
Supongamos que vamos a seleccionar la carpeta Música y esta carpeta contiene 3 más. Las carpetas hijas son: Aerosmith, Pink, Rolling Stones y cada una de estas tiene varios archivos dentro.
os.walk es capaz de buscar dentro de Música las 3 carpetas y ver que archivos hay dentro de estas, al final arroja 3 parámetros root, dirs, filelist.

Root indica cual es la fuente, en nuestro caso sera:
/home/geojorg/Música

Dirs indica todas las carpetas dentro de Root
["Aerosmith","Pink","Rolling Stones"]

Filelist indica todos los archivos dentro de Dirs
["Aerosmith - Just Push Play.ogg ","Pink - Just Like a Pill.mp3","Rolling Stones - Angie.mp3"]


Como pueden ver os.path no crea tuplas, crea listas y esto no es ideal, por eso hay que agregar la linea 16.


La linea 16 funciona de la siguiente forma. Para todos los archivos que están dentro de un valor que esta almacenado en filelist va a buscar algo. Ese algo es este comando endswith. Voy a explicar que hace entonces con un ejemplo


Ejemplo:
Tenemos los 3 archivos y ya los tenemos en una lista en columna que fue lo que logramos con el comando f for f in filelist
Quedaron representados entonces tal como se ve más abajo, el comando endswith se traduce al español de forma similar a "termina en" y lo que hace es buscar un patrón final dentro de un listado, en este caso lo que va a buscar es que la lista tenga archivos que terminen en "mp3, mpeg, avi, ogg" y los que terminen en alguna de esas extensiones los pondrá como validos (True) , los que no terminen en esas extensiones no serán validos (False) entonces los eliminara de la lista. El comando endswith siempre se aplica a una variable, en este caso se lo aplicamos a f por eso queda f.endswith y dentro del paréntesis estarán todos las extensiones (mp3,mpeg y demas) pero para evitar meter todo una lista de extensiones es más fácil crear una variable que contenga todas las extensiones que nos interese.

pattern = (".mp3",".mp4",".avi",".flv",".ogg")

Aerosmith - Just Push Play.ogg
Pink - Just Like a Pill.mp3
Rolling Stones - Angie.mp3

#Definicion del comando Abrir Carpeta def showAddFolder(self, widget): self.filterbox.set_name("All Media Files") for names, patterns in filepattern: self.filterbox.add_pattern(patterns) self.addfolder.add_filter(self.filterbox) respt = self.addfolder.run() self.addfolder.remove_filter(self.filterbox) self.addfolder.hide() if respt == -5: addmultiple = self.addfolder.get_filename() for root, dirs, filelist in os.walk(addmultiple): for allfiles in [f for f in filelist if f.endswith(pattern)]: self.medialist.append([allfiles,root])

Finalmente la linea 18 pondrá dentro del Gtk.Treeview los archivos y la ruta respectivamente en la columna 0 y 1.

En el próximo tutorial vamos a aprender que son los Gtk Tree Iters  y como se relacionan con el Gtk.Treeview, terminaremos entonces de organizar algunos botones que hacen falta como Limpiar, Arriba, Abajo y eliminar.

Cualquier duda no duden en ponerla en los comentarios.

No hay comentarios:

Publicar un comentario