visor  nibblesmx  tramas4life.tk  jmflores  Gunnar  LinuxMan  pcero  Zodman  demrit  alo 

Main

contact

Projects/Proyectos

Papers/textos

Resume / Curriculum

 Use OpenOffice.org

OpenSolaris: Innovation Matters

twitter

    Categories

    Tiras


    Tira Ecol
    Tira Ecol


    Tira LinuxHispano.net
    La Legión del Espacio
    La Legión del Espacio
    En el Sitio de Ciencia-ficción

    Recent Comments

    gtk

    christine 0.1.6
    CLick to enlarge
    This is the new release of Christine Media Player. This release include:

    HelpMenu.png

    1. Some bugfixes
    2. Reworked code in Sources list
    3. Reworked display.
    4. Improved import code (no more freeze while looking for the media files)
    5. Multiple Sources list.
    6. Translate Christine and Report a bug menuitems

    You can download it from sourceforge:

    markuz | general, Software_Development, Python, gtk, christine, FLOSS | Tuesday 29 April 2008 1:45pm | 1 comments

    Es facil, al inicio de tu aplicacion tendras que inicializar los threads, que son algo asi:

    gtk.gdk.threads_init()
     

    Esto lo tendras que hacer antes de iniciar algun thread. Y luego, al usar algun thread debes englobarlo dentro de

    gtk.threads_enter()
    thread.start_new(funcion, (arg1,arg2,argN))
    gtk.threads_leave()
     

    Solo recuerda que no debes manipular gtk fuera del thread en el que esta corriendo el ciclo principal (gtk.main_loop).

    Si lo que necesitas es estar cachando informacion en un thread aparte y modificar la interfaz (ej. Leyendo un socket y mostrando informacion de cuanto llevas leido) entonces usa alguna bandera y modifica tu apariencia en el thread principal, de lo contrario tendras problemas con gobject y glib.

    markuz | general, Software_Development, stuff, personal, Python, gtk, FLOSS | Thursday 10 April 2008 6:51pm | Comment on this

    sources.pngBien, hoy ha sido un pequenio dia para dar amor a christine, Hoy he tenido un poco de tiempo libre para 'descansar', Ayer cristina y yo nos fuimos a conocer Guanajuato, pronto pondre las fotos y la reseña.

    Hoy, despues de hacer los quehaceres de la casa me sente un rato a cubrir una necesidad en especial que he tenido en Christine. Bien, pues resulta que a cristina le gusta mucho la musica en español, en particular la movida, mientras que a mi me gusta mas la musica en inglés, El problema es que la gran mayoria de la musica en español la he copiado de varios lugares y no la tengo en mi directorio de musica tipico, y tampoco lo tengo dentro de mi lista de canciones normal. Que pasa cuando cristina quiere escuchar su musica, tengo que entrar en ~/.christine y copiar el archivo music a algun otro, despues copiar el archivo de musica de cristina a music, y lo mismo cuando quiero poner mi lista de canciones. Un poco engorroso, aunque no lo hago muy seguido. Hoy he hecho un pequeño cambio a christine de forma que es posible selecionar la lista de canciones. Por hoy, en este lado es suficiente, aun le falta pulir, pero lo hace con mas tiempo y despues.

    Tambien estuve trabajando un poco para corregir unos pequenios problemas con los menus, que no se muestran traducidos, esto debido a que en los archivos de descripcion de glade las etiquetas no tienen la propiedad translatable (en los menues). Tambien he agregado al SVN los archivos de traduccion creados en Launchpad. En fin, estos cambios ya estan disponibles en el SVN de christine.

    newMenu1.png

    markuz | general, Software_Development, personal, gtk, christine, FLOSS | Saturday 22 March 2008 9:43pm | Comment on this

    Foresight linux

    markuz | general, Humor, Internet, linux, gtk, FLOSS | Tuesday 11 December 2007 8:33pm | Comment on this

    Alguien sabe de algun algoritmo o forma para acelerar la insersion de elementos en un ListStore?. He estado haciendo pruebas con Christine sobre una lista de ~14000 canciones y mi pobre maquinita tarda entre 20 y 24 segundos para llenar el ListStore.

    Se, que podria mostrar Christine y dejar que una llamada con idle_add haga la chamba, es decir, christine se mostraria en menos de 1 segundo, pero el idle_add me retrasa mas la carga de la lista a unos 2 minutos.

    Alguien con algun comentario, enlace o similar, seria mas que apreciado.

    markuz | general, Software_Development, personal, linux, gtk, christine, FLOSS | Thursday 06 December 2007 3:24pm | 6 comments

    La mayoria de los widgets en Gtk tienen una ventana asociada, y no precisamente la ventana con decoracion que todo mundo ve. Gtk adiere una propiedad llama "window" a los widgets al ser empacados, o emparentados a otro widget contenedor.

    Generalmente estos widgets son de apariencia rectangular, pero es posible tunearlos para que tengan la forma que nosotros queremos. La forma mas facil de hacerlo es tomar una imagen un usarla como "Molde" para crar nuestro contenedor recortado. aunque tambien es posible dibujar lo que nosotros querramos usando las funciones de cairo sobre un contexto (Que en si, es lo que hacemos con la imagen molde, pero mucho mas sencillo).

    Lo que hacemos es obtener un molde a partir de una imagen, es decir, abrimos la imagen y creamos un gtk.gdk.Pixbuf, que es el mostraremos, pero podemos obtener el gtk.gdk.Pixmap y la mascara de este Pixbuf de forma que podamos usar dicha mascara para crear el contorno de nuestro widget.

    Los widgets, una vez empacados,como ya habia dicho obtienen una propiedad llamada window, que pertenece a la clase gtk.gdk.Window. Aquellos que ya se han puesto a dibuar algo con cairo se habran dado cuenta que se obtiene un contexto de un widget a partir de su gtk.gdk.Window.

    Bien. tambien es posible obtener este contexto de cairo a partir de un pixmap, hacer el dibujo molde y luego pegarselo a la ventana para que gtk.gdk sepa que partes ha de dibujar y cuales no.

    Veamos un pequenio ejemplo.

    class shapedWindow(gtk.DrawingArea):
            def __init__(self):
                    gtk.DrawingArea.__init__(self)

                    self.__pixbuf =  gtk.gdk.pixbuf_new_from_file('./logo.png')

                    self.connect('size-allocate',self.size_allocated)
                    self.connect('expose-event',self.do_expose_event)

                    self.set_size_request(self.__pixbuf.get_width(),
                                    self.__pixbuf.get_height())

           
            def size_allocated(self,win,allocation):
                    w,h = (allocation.width, allocation.height)
                    self.bitmap = gtk.gdk.Pixmap(None,w,h,1)
                    context = self.bitmap.cairo_create()
                   

                    self.do_expose_event(self,'',context)

                    parent = self.get_parent()
                    win.shape_combine_mask(self.bitmap,0,0)
                    parent.shape_combine_mask(self.bitmap,0,0)
                   
            def do_expose_event(self, widget, event,allocate = False):
                    if allocate:
                            context = allocate
                    else:
                            context = self.window.cairo_create()

                    if allocate:
                            context.set_operator(cairo.OPERATOR_DEST_OUT)
                            w,h = (self.allocation.width, self.allocation.height)
                            context.rectangle(0,0,w,h)
                            context.set_source_rgb(1,1,1)
                            context.paint()

                    context.move_to(0,0)

                    context.set_operator(cairo.OPERATOR_OVER)

                    if allocate:
                            pixmap,mask = self.__pixbuf.render_pixmap_and_mask()
                            context.set_source_pixmap(mask,0,0)
                    else:
                            context.set_source_pixbuf(self.__pixbuf,0,0)
                    context.paint()
           

    if __name__ == '__main__':
            window = gtk.Window()
            window.set_decorated(False)
            a = shapedWindow()
            window.add(a)
            window.show_all()
            gtk.main()

           
     

    Que es lo que hacemos aqui? bien, primero creamos un widget personalizado usando gtk.DrawingArea y conectamos la sennial size-allocate para poder establecer el tamanio de nuestro widget. Una vez llamada esta funcion creamos un pixmap vacio del tamanio de nuestro widget, que es el tamanio que nos ha dado el contenedor padre, este es un rectangulo como de costubre, con un ancho y alto. A este pixmap le sacaramos el cairo context, sobre el cual hemos de 'dibujar' nuestro molde.

    Como en este ejemplo el widget y su molde de la misma forma estoy aprovechado el metodo do_expose_event para hacer el dibujo inicial y despues hacer las funciones de redibujado en caso de un evento de expose.

    Quienes hacen la chamba aqui? bien, para el dibujo inicial de nuestro widget es context.set_source_from_pixmap(), aunque podriamos usar el mismo set_source_from_pixbuf he detectado problemas con colores en Windows, entonces no lo recomiendo.

    Otro que entra en juego y es el que le dice al widget 'orale cabron, apegate a esta forma' es win.shape_combine_mask(self.bitmap,0,0).

    De ahi, el ponerle contenido a nuestro widget no es mas que un amanipulacion de colores y demas dentro de nuestro contexto cairo. Que, es otro tema del que hablar, como 'dibujar' lo que queremos en nuestro widget usando su contexto cairo.

    Shaped Window widget

    Tamanio Completo

    Ciertamente, el logtipo de Christine es el widget 'recortado' face-smile.png

    markuz | general, Software_Development, stuff, personal, Python, gtk, Pictures, FLOSS | Friday 09 November 2007 5:19pm | Comment on this

    Que bonito es usar sockets con python. Esta semana he estado trabajando con sockets para crear una interfaz de servidor y clientes que se comunican unos con otros a traves del servidor. En la imagen de abajo tenemos dos clientes, uno tiene su interfaz en GTK+ que es el que corresponde a la termina de la esquina inferior izquierda. Otro cliente es puro texto, que es el que esta en la parte superior, y el servidor es la terminal alargada que esta en el centro.

    screenshot5.png

    Lo que muestran las terminales no es mas que pura informacion loggeada usando el modulo logging de python

    En los proximos dias, ya que tenga el codigo mas limpio vere la forma de ponerlo al publico.

    markuz | general, Software_Development, personal, Python, gtk, Pictures | Wednesday 31 October 2007 6:22pm | Comment on this

    Perfecto. En esta semana me ha tocado estar trabajando sobre un programita que ando haciendo, el cual debe correr sobre Linux y MS Windows >= 2000. El desarrollo se esta haciendo en Python usando GTK para la interfaz grafica, pero me he encontrado uno que otro problemita con GTK, sobre todo con el manejo de ventanas, aunque el que mas tiempo me ha llevado ha sido el de impresion.

    Gtk+ a partir de la version 2.10 incluye soporte para impreision en Linux y otros Unix'es gracias a CUPS, mientras que en Windows lo hace de manera nativa con el sistema de impresion de Windows.

    Debo decir que en linux esta cosa es la maravilla, En windows no tanto, pero funciona decentemente si tus requerimientos no son tan especiales.

    Los requerimientos para imprimir son estos:

    • Debe imprimir en la impresora por defecto
      • NO debe mostrar el dialogo de seleccion de impresora
    • Debe imprimir en el tamanio determinado por el programa

    En linux, repito, esto es una maravilla, solo le digo imprime usando la constante gtk.PRINT_OPERATION_PRINT y con esto no me muestra el cuadro de dialogo, previamente he creado la operacion de impresion y le he dicho que seleccione la impresora por defecto, en linux, si en settings.set_printer() le pasas el parametro '' usa la impresora por defecto, es mas, si no usas el metodo set_printer usa la impresora por defecto.

    Pero en Windows la cosa no es tan bonita. para empezar Siempre muestra el cuadro de seleccion de impresora (punto menos). Y para acabarla de amolar, aunque tengas una impresora predeterminada y esta impresora este seleccionada mandas imprimir (Alt +m o ENTER) habra un error porque GTK no ha configurado las cabeceras de impresion para mandarle el 'win32-driver', 'win32-driver-extra' y otros parametros fumados de los que Windows sabe. Obviamente, si seleccionas otra impresora y regresas a la que esta por defecto estos parametros son llenados y entonces la impresion funciona "bien". Obviamente, como no queremos que el usuario vea el cuadro de impresion esto no es opcion.

    Lo siguiente es, obtener la impresora por defecto y mandar establecer los encabezados, para esto se pueden valer del modulo win32print

    import win32print

    printerName = win32print.GetDefaultPrinter()
    printer = win32print.OpenPrinter(printerName)
    printerValues = win32print.GetPrinter(printer,2)
    dir(printerValues['pDevMode'])
     

    Y pueden valerse del gtk.PrintSettings.set() para poner los encabezados.

    Esto les sera util cuando ustedes quieran mostrar el cuadro de impresion, a fin de que lo muestre y espere una configuracion por parte del usuari, o en caso de que no se configure nada por parte del usuario, usar las configuraciones por defecto.

    Hasta aqui todo bien, pero, Yo no quiero el cuadro de impresion!, solo quiero que imprima.

    Bien, yo no queria hacerlo asi, pero pues bueno, no hay de otra.

    if os.name == 'nt':
            filename = './ultimafactura.pdf'
            op.set_export_filename(filename)
            action = gtk.PRINT_OPERATION_ACTION_EXPORT
    elif '-d' in sys.argv:
            action = gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG
    else:
            action = gtk.PRINT_OPERATION_ACTION_PRINT
    try:
            response = op.run(action)
    except:
            response = gtk.PRINT_OPERATION_RESULT_ERROR
    if response == gtk.PRINT_OPERATION_RESULT_ERROR:
            settings = op.get_print_settings()
            settings.foreach(funcPrintKeys)
            print "Hubo un error a imprimir"
    elif response == gtk.PRINT_OPERATION_RESULT_APPLY:
            if os.name == 'nt':
                    filename = './ultimafactura.pdf'
                    import win32api
                    win32api.ShellExecute(0,
                                    'print',
                                    filename,
                                    None,
                                    '.',
                                    0)
     

    La solucion ha sido crear un archivo PDF, usando el PrintOperation.set_export_filename() para despues usar win32api.ShellExecute() para imprimir.

    Que es lo que hace ShellExecute?. Bien, ejecutara el comando que tu le des, en este caso 'print' sobre el archivo dado por el siguiente parametro "filaname", el siguiente parametro son los parametros al programa que va a realizar la operacion, el siguiente, el directorio de trabajo y por ultimo un valor entre 0 y 1 que dice si se ha de mostrar o no la ventana del programa que ha de realizar la operacion.

    Para esto, es necesario tener en Windows un programa que pueda abrir e imprimir PDF. Obviamente el mas conocido es Adobe Acrobat Reader, pero Adobe Acrobat Reader es un Monstruo si lo unico que queremos es impresion. Asi que, lo que he hecho es utilizar Foxit PDF Reader, el cual es mucho mas ligero y rapido.

    Y eso es todo, ese ha sido el cucharazo porque GTK por defecto no te utiliza la impresora por defecto, ni te esconde el cuadro de impresion en Windows.

    En fin. el chiste es lograr que las cosas jalen.

    Un ejemplo sencillo de impresion lo pueden encontrar Aqui

    markuz | general, Software_Development, Python, gtk, FLOSS | Friday 19 October 2007 10:18am | Comment on this

    El equipo de desarrollo de Christine se complace en presentarles la nueva version de Christine, 0.1.1, Esta version es una version corregida de Christine 0.1, es decir, no implementa cosas nuevas, solo mejora lo que ya estaba.

    Pueden descargar las fuentes de Christine 0.1.1 Aqui, y revisar las notas de liberacion Aqui.

    Gracias a todos los que han cooperado con el desarrollo de Christine.

    markuz | general, Software_Development, personal, Python, gtk, christine, FLOSS | Friday 21 September 2007 2:10pm | Comment on this

    Despues de crear el widget en puesto en el post anterior, hoy me lo he implementado en el sistema que estamos creando en ICT Consulting. El video esta chidin, pero Google lo hace ver horrible. En fin, es solo demostrativo.

    widgetTest.ogg

    markuz | general, Software_Development, stuff, personal, Python, gtk, ICTC | Friday 14 September 2007 4:44pm | Comment on this

    Uno de los widgets menos usados en GTK es el gtk.Fixed, Este contenedor nos permite poner widgets de manera estatica en nuestra aplicacion. Es decir, si la ventana cambia de tamanio los widgets no se redimencionaran y tampoco cambiaran de posicion. Pocos lo utilizan por esto, pero a veces es necesario.

    Pues resulta que en una de las aplicaciones lo tengo asi, simplemente porque los widgets NO se tienen que mover ni cambiar de tamanio si la ventana se redimenciona, aqui yo lo veo como algo bueno. En fin, El problema del GtkFixed es que nomas no me cacha los eventos, y meterlo en un gtk.EventBox me parece no tan optimo, puesto que yo quiero que los eventos los cache el Widget, no un EventBox.

    Mi primer intento de solucion: Crear una clase que herede de gtk.Fixed y cachar los eventos para que cuando el cursor este dentro de un punto determinado se pueda redimencionar al muy puro estilo de click-arrastra-suelta. Problema, gtk.Fixed no me cacha los eventos, incluso si se los agrego a manita con gtk.Fixed.add_events.

    Segundo intento: Hereda primero de un gtk.EventBox y luego de un Fixed: Si cacha los eventos, No te muestra ni madres. Inviertelo, Si te dibuja, pero no te cacha los eventos... (ya me estoy desesperando)

    La solucion?, Bueno, nunca le habia echado el ojo al gtk.Layout, entonces heredo de un gtk.Layout primero, este no me cacha los eventos, pero, me permite dibujar como si fuera un gtk.DrawingArea aunque tienes que dibujar sobre el bin_window de tu layout (gtk.Layout.bin_window) en lugar del window como tipicamente se hace en gtk.DrawingArea. Bien, tu segunda herencia es de un EventBox para poder cachar las seniales, y listo face-smile.png .

    Es importante que Primero se herede de gtk.Layout y luego de algun otro widget (gtk.DrawingArea tambien funciona) para que Gtk no reniegue al tratar de agregar widgets a tu gtk.Layout.

    El codigo seria mas o menos asi (Estoy seguro que de alguna manera se puede mejorar):

    class groupWidget(gtk.Layout,gtk.EventBox):
            '''
            Una version modificada del gtk.Fixed
            '
    ''
            def __init__(self):
                    gtk.Layout.__init__(self)
                    gtk.EventBox.__init__(self)

                    self.__buttonPressed = False

                    self.set_name('groupWidget')
                    self.set_size_request(50,50)
                    self.set_property('events',
                                    gtk.gdk.EXPOSURE_MASK |
                                    gtk.gdk.ENTER_NOTIFY_MASK|
                                    gtk.gdk.POINTER_MOTION_MASK |
                                    gtk.gdk.BUTTON_RELEASE_MASK |
                                    gtk.gdk.BUTTON_PRESS_MASK )
                    self.add_events(
                                    gtk.gdk.EXPOSURE_MASK |
                                    gtk.gdk.ENTER_NOTIFY_MASK|
                                    gtk.gdk.POINTER_MOTION_MASK |
                                    gtk.gdk.BUTTON_RELEASE_MASK |
                                    gtk.gdk.BUTTON_PRESS_MASK )

                    self.connect('expose-event',self.__exposeEvent)
                    self.connect('motion-notify-event',
                                    self.__motionNotify)

                    self.connect('button-press-event',
                                    self.__buttonPressEvent)
                    self.connect('button-release-event',
                                    self.__buttonReleaseEvent)
           
            def __motionNotify(self,widget,event):
                    if self.__buttonPressed:
                            x,y = self.get_pointer()
                            if (x,y ) > (0,0):
                                    self.set_size_request(x,y)
                                    self.__lastWH= [x,y]

            def __buttonPressEvent(self,widget,event):
                    w,h = self.__lastWH
                    px,py = self.get_pointer()
                    if event.button == 1:
                            if w > px > w-5 and  h > py > h-6:
                                    self.__buttonPressed = True
           
            def __buttonReleaseEvent(self,widget,event):
                    if event.button == 1:
                            self.__buttonPressed = False

            def __exposeEvent(self,widget,event):
                    '''
                    Encargada de dibujar el widget
                    '
    ''
                    context = self.bin_window.cairo_create()
                    x,y,w,h = self.allocation
                    self.__lastWH = [w,h]
                    context.set_line_width(1)
                    context.set_antialias(cairo.ANTIALIAS_NONE)

                    #Dibujamos el relleno y el borde
                    context.move_to(0,0)
                    context.rectangle(1,0,w-1,h-1)
                    context.rectangle(1,0,w-1,h-1)
                    context.set_source_rgba(1,1,1,0.5)
                    context.fill_preserve()
                    context.set_source_rgb(0,0,0)
                    context.stroke()

                    #Dibujamos un pequenio rectangulito
                    # en la parte inferior derecha.
                    context.rectangle(w-5,h-6,5,5)
                    context.set_source_rgb(0.5,0.5,0.5)
                    context.stroke()

     

    Y se deberia ver asi:

    En el video se puede apreciar que el boton esta dentro del contenedor, por eso de corta cuando el tamanio del contenedor es menor (se pueden usar Scrollbars gracias a la capacidad de gtk.Layout.

    markuz | general, Software_Development, stuff, Python, gtk, FLOSS | Thursday 13 September 2007 4:23pm | Comment on this

    Esto Iba a ser un comentario mas, pero creo que seria bueno que estuviera a vista de todos.

    Armando: En las escuela esta muy dificil que te ensenien a usar PHP, y esta aun mas dificil que te ensenien a usar Python, mas cabron aun, que te ensenien a usar GTK. Desafortunadamente en mexico las escuelas estan dedicadas a enseniar cosas como Java o .NET porque:

    1.- Es un circulo vicioso, los profesores lo saben, lo ensenian a los alumnos, los alumnos aprenden, la mayoria de los alumnos no aprenden otra cosa, y cuando les toca enseniar solo pueden enseniar lo que saben, asi terminan dando Java.

    2.- Muchas escuelas estan casadas con Microsoft, asi que por fuerza lo han de dar face-smile.png .

    De PHP hay infinidad de libros, y tutoriales libres muy buenos por la red, el libro con el que yo empece con PHP es con el de 'Proyectos Profesionales con PHP' de editorial ANAYA,

    De Python, te recomiendo el tutorial de python que esta en la documentacion de python, 'Dive Into Python' y 'How to think like a computer scientist learning with python' .

    De Gtk, Hay un tutorial muy bueno en la documentacion de PyGTK.

    Un comentario, si piensas aprender PHP para usar GTK, te recomiendo mejor aprender Python para usarlo con GTK.

    markuz | general, Software_Development, stuff, personal, Python, php, gtk, FLOSS | Thursday 09 August 2007 3:35pm | 5 comments

    En esta semana, he estado trabajando en un programita que se mete con la base de datos del CRM que usan en ICTC, resulta que en el CRM se tienen tareas, clientes y demas cosas, pero hay que tener el navegador web abierto para poder echarle un ojo a las tareas pendientes, o para obtener informacion de algun cliente. Bueno, mi chamba ha sido que con Python y GTK haga una pequenia aplicacioncita que se meta en el area de notificiacion y desde la cual facilmente se puedan consultar las tareas, los clientes y otras cosas.

    Aun no termino el programa, me faltan varios detalles, pero para 2,3 dias que llevo en el vamos bien. Lo que me encanta es que programo desde linux con Vim y pruebo en windows. Obviamente, no se permite que cada maquina tenga una conexion directa con base de datos, asi que mejor abrimos un socket en una maquina 'servidor' y los clientes solo piden datos ahi.

    I love GTK

    En GNU/Linux

    I love GTK

    En Windows

    markuz | general, Software_Development, Python, gtk, FLOSS | Wednesday 08 August 2007 8:34am | 2 comments

    Como han de saber soy un "Fans" numero 1 de GTK. Me gusta mucho su apariencia y me gusta mucho programar usando este conjunto de bibliotecas, aunque sea en Python, Bien, Hoy para variarle, me he puesto a trabajar con WindowMaker, WIndowMaker esta bien, me encanta porque

    1. Es muy ligero
    2. Me da la sensacion de que trabajo con otro manejador de ventanas (XFCE me hace sentir que ando en una version rebajada de GNOME, disculpen, asi lo siento, no es malo, claro que no, pero asi lo siento)
    3. Se ve chingon y te consigues viejas de a monton usando WindowMaker tongue.png

    En fin. esta chidin el WindowMaker, de acuerdo a mis gustos no para usarlo siempre, pero si eventualmente cuando no quieres cargar todo el entorno de GNOME, lo malo es que las aplicaciones GTK se ven feisimas!!, simplemente porque no tienen ningun theme aplicado, funcionan igual, pero se ven fellonas.

    Solucion: gtk+ 2.0 Change Theme. El chunchecito este les deja cambiar el theme de GTK sin tener que arrancar el demonio de configuracion de Gnome, probé otro por ahi, pero como nomas no peló ya se me olvido su nombre, ha si, gtk-theme-switcher o algo asi. En fin, si usan algun manejador de ventanas que no les pone el theme en GTK, usen este, esta muy bueno, y no me dio broncas en compilada. es mas, no necesitas instalarlo, solo compila y desde ahi corres el gtk-chtheme y listones.

    markuz | general, Humor, stuff, personal, GNU, gnome, linux, slackware, gtk, FLOSS | Sunday 29 July 2007 2:44pm | Comment on this

    Bien, hoy es mi cumpleaños, gracias a todos los que no me han felicidado hasta ahora, y gracias a todos los que ya me felicitaron.

    He liberado la primera version de Christine, tal vez no es tan estable como yo quisiera, pero tengo planes par a christine que no van con el codigo que tengo ahorita, asi que lo mejor será liberar esto y empezar a codear en lo siguiente. Si encuentran bugs ya saben Donde reportarlos.

    Que cambio con respecto de la 0.1rc2?. Bien corregi varias cosas, y mejoré un poco algunas otras. Las correcciones no las recuerdo ahorita porque por lo general se almacenan en mi memoria temporal. Y las mejoras, pues mejore un poco lo del soporte para estaciones de radio y playlist m3u y el display que ahora usa los colores del theme.

    Puedes descargar christine 0.1 Aqui.

    markuz | general, Software_Development, personal, gtk, christine, FLOSS | Sunday 29 July 2007 1:29pm | 4 comments

    Para dibujar usando cairo por lo general creas un objeto heredando propiedades de gtk.DrawingArea. y obviamente, tenemos un metodo para el redibujado. Dentro de ese metodo metemos esto:

    def setPixbuf(self,pixbuf):
            if type(pixbuf) != gtk.gdk.Pixbuf:
                    raise TypeError("Pixbuf debe ser %s recibido %s"%(gtk.gdk.Pixbuf, type(pixbuf)))
            self.__Pixbuf = pixbuf
            self.emit("expose-event",gtk.gdk.Event(gtk.gdk.EXPOSE))

    def exposeEvent(self, widget,event):
            x,y,w,h = self.allocation
            try:
                    context =  self.window.cairo_create()
            except AttributeError:
                    return True

            if self.__Pixbuf != None:
                    scaledPixbuf = self.__Pixbuf.scale_simple(ancho,
                                    alto,
                                    gtk.gdk.INTERP_BILINEAR)
                    ct = gtk.gdk.CairoContext(context)
                    ct.set_source_pixbuf(scaledPixbuf,BORDER_WIDTH,BORDER_WIDTH)
                    context.paint()
                    context.stroke()

     

    Y listo face-smile.png

    markuz | general, Software_Development, stuff, Python, gtk, FLOSS | Saturday 21 July 2007 10:52am | Comment on this
    markuz | general, stuff, personal, gnome, slackware, gtk, Pictures, FLOSS | Wednesday 18 July 2007 5:08pm | Comment on this

    El cambiar el color de los widgets no es recomendable, en primera, porque no todos tenemos los mismos gustos, y de ahi se deriva la segunda, el usuario puede cambiar el theme y hacer que el texto que pusimos en nuestro widget deje de verse o que se vea mal.

    Lo ideal para cambiar el color de un widget seria dejarlo al libre gusto del usuario, pero a veces necesitamos que un widget tenga X o Y color (gimmie?). Bien para cambiar el color de un widget basta con un simple:

    map = widget.get_colormap()
    color = map.alloc_color("white") #Se puede usar codigo RGB #FFFFFF
    widget.modify_bg(gtk.STATE_NORMAL,color)

     

    Ciertamente, no es lo mejor, pero puede que lo necesitemos, y mejor es tenerlo y saber como hacerlo.

    markuz | general, Software_Development, Stupid things, stuff, Python, gtk, FLOSS | Friday 08 June 2007 1:15pm | Comment on this

    Ok, I think christine is getting closer to 0.1, wich will be the fist stable. It complies with my goals: being a media player small and fat free. Everything seems to be fine in my machine, from code in the svn and the code in the tar.bz created by make.

    Anyway, I need you to test it before I upload it to sourceforge.net servers.

    get it at: http://islascruz.org/html/data/files/christine-0.1rc.tar.bz2

    And what's the new in christine 0.1 againts 0.0.3??

    • Faster, I mean, really faster import.
    • Very simple radio station support.
    • Drag'n'Drop queue add.
    • lots of bugs fixed.

    Go, test it and report your bugs face-smile.png

    markuz | general, Software_Development, personal, Python, gtk, christine, FLOSS | Friday 01 June 2007 4:26pm | Comment on this

    ... cuando usas una iteración.

    Suponiendo que tienes que iterar sobre 100,000 elementos (no se que, solo son elementos de algo), y tu aplicacion tiene que procesar esto, obviamente, va tardar algo y quieres que tus usuarios esten "entretenidos" mientras la aplicacion trabaja, asi evitas que se aburran y sobre todo, evitas que piensen que tu aplicación se ha atorado y terminen matandola.

    Pero, por que se congela la interface grafica si esas ejecutando algo en "background"?, bien, la solucion es simple. GTK+ captura los enventos y realiza sus tareas por ciclos, de ahi el uso del gtk.main() para iniciar el ciclo. pero cuando tu aplicacion entra en un ciclo este no devuelve el control del programa a GTK hasta que termina el ciclo que estas realizando por lo tanto, el ciclo de GTK no termina y se actualiza hasta que se le devuelve el control.

    progress = gtk.ProgressBar()
    fraction = 0

    for i in xrange(100000):
       print "Estoy congelando la interfaz!!"
       sleep(1)
       fraction += 1/100000
       #No se actualizará porque GTK no puede actualizar, no tiene el control
       progress.set_fraction(fraction)

    # Uff, por fin!!

     

    Una solucion que habia estado usando era dividir mi ciclo y realizarlo por pedacitos usando gobject.timeout_add(). este timer te permite ejecutar una funcion/metodo cada determinado tiempo, logrando evitar el "freezeo", lo malo s que no es tan rapido como quisieramos y peor aun, tienes que trozar tu ciclo, en si no realizas un ciclo con un for, o while o algo asi, sino que ejecutas la funcion un chingo de veces, mientras regreses el valor True, y sales regresando el valor False.

    progress = gtk.ProgessBar()
    fraction = 0
    def funcion():
       fraction += 1/100000
       progress.set_fraction(fraction)
        if fraction == 1:
            return False
        return True

    gobject.timeout_add(200, funcion) #ejecutar funcion cada 200 milisegundos

     

    La solucion mas limpia, y mejor es usar

    while gtk.events_pending():
                     gtk.main_iteration_do(False)

     

    Esto se usa dentro de tu ciclo bloqueador. Por ejemplo:

    progress = gtk.ProgressBar()
    fraction = 0

    for i in xrange(100000):
       fraction += 1/100000
       progress.set_fraction(fraction)
       #Detenemos todo y dejamos que GTK tenga control y realice sus tareas pendientes
        while gtk.events_pending():
           gtk.main_iteration_do(False)

    # Uff, por fin!!

     

    Espero les sea util. Con esto no solo evitamos el congelamiento de la aplicacion, sino que el ciclo se realiza tan rapido como el CPU puede hacerlo, usando el timer, no importa que tan rapido sea el CPU, siempre terminara en el mismo tiempo.

    markuz | general, Software_Development, gtk, FLOSS | Thursday 17 May 2007 10:30pm | 6 comments

    Today Finish the Christine Bug Squash I'm Happy because we (nibblesmx and I) fixed some bugs, 5 bug reports where fixed and closed while some others are still open waiting for some user testing (even that they where fixed and in my machine it works fine).

    Tanks to Pcero and Jose Oviedo, for their bug reports.

    Things that I like more about Christine is:

    • Support for radio stations. (via Open Remote) Now you can just copy the Url of the .pls or m3u file and christine will play it.
    • Improved the Visualization mode. Now it works on the radio stations too. And if you aren't playin Christine and activate it, when you hit the play button it will work (no wait until next song or deactivate and reactivate).
    • Improved the time for importing I have been working with signals, and at least in my machine it runs smooth, Importing my 1865 songs in just 2 or 3 minutes (hey, fetching all that data isn't easy in GStreamer, and I know there are some other libraries, but we have to be able to fecth this data (tags) with all Media Files supported by GStreamer not only mp3 and vorbis ogg)

    Some things still need some work:

    • Some keyboard bindings are broken.
    • The player display (where videos and visualization shows up) steals events if it is in focus.
    • There are a bunch of features that I'd like to include in next release.
    markuz | general, Software_Development, personal, Python, gtk, christine, FLOSS | Sunday 22 April 2007 10:04pm | Comment on this

    Se llevará a cabo un bug squash de christine este fin de semana, buscando la liberación de la primera estable. Si usas christine y quieres cooperar, reporta tu bug en el Bug Tracker. Los bugs permanecerán abiertos hasta el fin de semana, en donde les daremos mate.

    markuz | general, Software_Development, personal, Python, gtk, christine, FLOSS | Tuesday 17 April 2007 10:36am | Comment on this

    I took a break from my "paid" work yesterday and I start hacking Christine again. Trying to make it run again in my system, I found lots of bugs, most of them for non declared variables or misspelled names, some other where making use of the wrong widget. Anyway, it seems to be running right, well. not that right, but at least it play music and video again tongue.png . I think that code clean will be finished soon.

    bigfixing Christine

    I also integrate a "--devel" option in christine, that let you work with christine from the source code directory. I mean, checkout the christine code, then run autogen.sh, run configure, make, and then just run christine like this: "./christine --devel" from the top of the source directory. Useful for people (coff coff developers coff coff) that want to try, not to install.

    As always, my invitation to Check it out, test it, and fill our Bug tracker

    markuz | general, Software_Development, Python, gtk, christine, FLOSS | Friday 23 March 2007 7:57am | 2 comments

    Major changes in christine for today:

    • Package lib_christine have been changed to libchristine.
    • Most of the bugs generated by the code clean are solved.
    • and....

    http://www.christine-project.org/

    markuz | general, Software_Development, personal, Python, gtk, christine, FLOSS | Wednesday 14 March 2007 7:11pm | Comment on this

    Oks, this have been happening in the christine world.

    • demrit have been working in the code clean and he is doing a very great job.
    • He also create some clases like Singleton and Validator, and improve some others.
    • Christine has been moved from cvs to svn.
    • There are some ideas about the Plugins stuff, we are still researching.
    • We are three developers now (demrit, nibblesmx and me, although only demrit have been working in this week).
    • SVN code is broken by now but it will be fixed when the code clean gets done.
    markuz | general, Software_Development, personal, Python, gtk, christine, FLOSS | Friday 09 March 2007 9:49am | Comment on this

    Si bien el soporte para impresion con una interface escrita en GTK+ dentro de Linux tiene ya mucho tiempo con los usuarios, se ha dado gracias a Gnome, mas no por GTK. Hasta hace poco GTK+ carecía de un API para impresión, y muchos tenian que integrar Gnome para poder hacer uso de este servicio.

    Bien, a partir de la version 2.10 de GTK+ se cuenta con un API para imprimir que si bien por ahora se utiliza en sistemas UNIX se pretende que sea un sistema portable para imprimir, es decir que con el mismo codigo se pueda imprimir tanto en Unix como en Windows.

    Bien, hoy por la mañana, yo digo que fue por que madrugué me avente un clavado en busqueda de documentacion para usar la API de impresiond e GTK (pygtk precisamente) y no encontre ni madres, mas que un ejemplo que vi en este documento (Páginas 12 y 13). Y usando ese ejemplo hice lo mismo en Python:

    #!/usr/bin/env python

    import gtk,cairo

    def draw_page(PrintOperation,PrintContext,Page):
        context = PrintContext.get_cairo_context()
        context.set_source_rgb(1,0,0)
        context.rectangle(0,0,PrintContext.get_width(),50)
        context.fill()

        context.set_source_rgb(0,0,0)
        context.move_to(90,75)
        context.line_to(60,80)
        context.curve_to(40,70,65,65,70,60)
        context.set_line_join(cairo.LINE_JOIN_ROUND)
        context.set_line_width(5)
        context.stroke()

    window = gtk.Window()
    window.connect("destroy",gtk.main_quit)
    op = gtk.PrintOperation()
    settings = gtk.PrintSettings()
    op.set_print_settings(settings)
    op.set_n_pages(1)
    op.set_unit(gtk.UNIT_MM)
    op.connect("draw_page",draw_page)
    op.connect("done",gtk.main_quit)
    response = op.run(gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG)
    if response == gtk.PRINT_OPERATION_RESULT_APPLY:
        settings = op.get_print_settings()
    gtk.main()

     

    y el resultado a la hora de imprimir es este:

    Print dialog in GTK dsc05756.jpg
    Como ven, no es tan dificil, lo dificil es "dibujar" el documento con Cairo face-smile.png . En fin..

    Nota: No, no es degradado el rectangulo ese, mi tonner rojo ya esta valiendo madres.

    markuz | general, Software_Development, Python, gtk, FLOSS | Monday 22 January 2007 11:43am | Comment on this

    Lazy days: I have been so lazy this days, this is something that I believe is temporal, just like one of those days that I may spend coding all the fucking day. And I know what to do, I know what needs to be done, and I would like to do it, but im so lazy.

    And that's why christine is taking to long in get mature. I spit some lines in the day but not a real work. I just didn't really feel so inspired.

    But.. There is something... Plugins:

    I have, in this few inspirations, work over the plugins stuff, Its still very very early but, I'm trying to make a god environment to become christine into a plugable application. At this time I'm just creating the public interface, but also converting the "show properties" action (menu: edit/show properties) that show the tags of the selected item in the library, to a plugin. So, isn't by now a lib_christine package module. Ok, here is the shot:

    Show properties

    Somebody with plugins implementation knownledge and good will to work over this stuff, give me an email face-smile.png .

    markuz | general, Software_Development, Python, gtk, christine, FLOSS | Saturday 13 January 2007 7:44pm | Comment on this

    Si estas escribiendo un programa, como yo, a veces querras que un proceso indique a otro cuando ha terminado, o que le diga que tal evento ha ocurrido. Bien, Gtk+ es genial para esto porque ya implementa un sistema de señales que podemos ajustar a nuestro programa.

    Por ejemplo, en christine a la hora de importar archivos los someto a un "descubridor", este chunche abre el archivo, busca por las etiquetas y avisa cuando hay etiquetas, luego, la biblioteca actualiza los campos con las etiquetas. En realidad no es mas que un playbin con fakesinks del cual tomo el bus y lo conecto a un watcher, cuando existe un mensaje de etiquetas agrego las respectivas etiquetas a la lista.

    Hasta aqui bien, pero al momento christine lo que hace al importar los archivos es utilizar un repetidor con "gobject.timeout_add", la ventaja es que funciona bien y es decentemente rapido, lo malo es que en CPUs con buenca capacidad no es enteramente aprovechada esta capacidad. Posible solucion, que se emita una señal a quien llama cuando se descubran las etiquetas.

    Para hacer que nuestro objeto emita la señal heredaremos de gtk.Widget y haremos esto:

    class library(gtk.Widget):
    ...
        def __init__(self):
            gobject.signal_new("tags-found",self,
                gobject.SIGNAL_RUN_LAST,
                gobject.TYPE_NONE,
                (gobject.TYPE_PYOBJECT,))

        def add_file(file):
            #algun codigo para agrear el archivo...

        def watcher(self,bus,message):
            # Algun codigo para manejar los mensajes
            self.emit("tags-found",self)

    def do_something(widget,userdata):
        #Codigo para manejar la señal.

    li = library()
    li.connect("tags-found",do_something)
     

    Heredamos gtk.Widget para tener acceso a algunos elementos de gobject, si no se lo ponemos nos va a rebusnar sobre gobject.TYPE_PYOBJECT y utilizamos gobject.signal_new para definir nuestra señal. Después utilizamos self.emit para emitir la señal. Obviamente, quien tenga una instancia a nuestro objeto debe conectar la señal a un manejador.

    De esta forma nuestra clase library que resulta en un objeto heredado de gtk.Widget y no se empaqueta ni se muestra ni nada o aunque contenga otros widgets (por ejemplo, un gtk.TreeView y un gtk.TreeModel), puede emitir señales y puede alertar (en este ejemplo) que se han encontrado las etiquetas y que es hora de cargar un nuevo archivo.

    markuz | general, Software_Development, Python, gtk, FLOSS | Sunday 07 January 2007 8:45pm | Comment on this

    Bien, desde ayer en la noche antes de dormir, me puse a codear un poco de la implementacion en C de un fragmento de la clase library del modulo de mismo nombre en Christine.

    Debo decir que en Python, me sorprende que la velocidad pocas veces sea un problema face-smile.png , y que la diferencia de velocidad entre C y Python no es mucha, aun asi hice esta implementacion mas como prueba que como algo que es realmente necesario, es como un "pega y corre".

    Christine normalmente toma poco menos de 2 segundos en crear todo, desde cargarse las interfaces, crear el modelo y lo mas pesado, llenar el modelo con las 1751 canciones que tengo, que bueno, no son muchas. La diferencia no es mucha, pero repito, no son tantas canciones y si alguien por ahi mete unos 5000 elementos no quiero que espere 10 segundos a que se cargue christine.

    He aqui la prueba face-smile.png :

    pgen_model
    0
    set: /apps/christine/control/CONTROL_STAT 1
    Not to miniviewer
    set: /apps/christine/ui/small_view False
    set: /apps/christine/control/volume 0.5

    real 0m1.327s <==Hecho con Python
    user 0m1.057s
    sys 0m0.084s
    cgen_model
    0
    set: /apps/christine/control/CONTROL_STAT 1
    Not to miniviewer
    set: /apps/christine/ui/small_view False
    set: /apps/christine/control/volume 0.5

    real 0m0.990s <== Hecho con C
    user 0m0.785s
    sys 0m0.048s

    No elimine el metodo en python, simplemente hice un empapelado y al utilizar "--clibrary" como argumento en la linea de comandos ejecuta el metodo en C (cgen_model) mientras que ejecutando christine directamente carga con el metodo hecho en Python (pgen_model). El parametro "-q" hace que Christine se muera (sys.exit()) al terminar de cargar todo, obviamente nomas ves que aparece la ventana un segundo y zas, ya se fue.

    En fin, solo queria comentar esto face-smile.png . Igual y hace implementaciones en C de otros puntos criticos de Christine face-devil-grin.png

    markuz | general, Software_Development, personal, Python, gtk, christine, FLOSS | Thursday 14 December 2006 3:04pm | Comment on this

    Se acuerda usted de esto, pues es una aplicacioncita que me hice hace unos cuantos meses para llevar el control de mis chucherias que tengo y que vendo en mi negocio, originalmente (y hasta el momento) esta pensado primordialmente para que cumpla su objetivo mera y razamente, o sea que no tiene todas esas mamadas y complicadeces que tiene esas aplicaciones comerciales porque simplemente No las necesito.

    Bien, continuando, la chucheria esta esta escrita en Python (ya lo sabias, pero como quiera va) y se conecta con una base de datos manejada por MySQL. Lo shido es que Python es multiplataforma, MySQL tambien, GTK Igual, PyGTK... yer, o sea, lo que necesita esta cosa para trabajar existe al menos en las dos plataformas que uso: Windows y Linux.

    Pues, bien, este mismo proyecto lo estoy agarrando de ejemplo para mi tesis, mi tesis habla sobre como desarrollar aplicaciones de manera rapida con Python, GTK y Glade, asi que es el ejemplo perfecto, porque aparte de ser un ejemplo sencillo, que escribi en unos cuantos dias, muestra el uso de la mayoria de los widgets de GTK (Windows, dialogs, Scrollbars, SpinButton, ToolBar, botones [checkbuton, normales, toolbutton], Modelos, Treeview, TextView, Frames, etc..). Peeeero, asi como estaba no me sirve, esta demasiadamente sencilla, ranfla y con un chingo de cosas que faltan por pulir y a las que no le dedique tiempo, por que?, porque soy webon.

    Bien, antier, ayer y hoy me p