Marco Islas Blog Software_Development http://islascruz.org/html markuz@islascruz.org (Marco Antonio Islas Cruz) 2005-2007, Marco Antonio Islas Cruz Sun, 17 Aug 2008 23:04:53 -0500 JAWS 0.7.4 <![CDATA[ Christine using 6Mb ]]>

screenshot3.png, originally uploaded by markuz.

This is a screenshot quite surprising for me, this is the gnome-system-monitor saying that christine uses just 6Mb of my RAM. I was looking for memory leaks in one of the applications that I'm currently developing in ICT Consulting, and I found that the memory used by one program, that memory that just belongs to the program is the Writeable memory and that is the memory you should be aware.

I have to say, christine was doing nothing, Just launch it and listen some music, then for one reason that I don't remember, just set it to pause and I get over another task, now, looking at the process table, christine is using more thatn 6 Mb.

btw.. Im using Christine 0.1.6.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Christineusing6Mb markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Christineusing6Mb Sun, 17 Aug 2008 23:04:53 -0500
<![CDATA[ WTF! Recursive errors. ]]>

wtf !, originally uploaded by markuz.

An internal error ocurred while showing an internal error.

Update:

@shakaran: In Eclipse 3.4, trying to install some components.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/wtfrecursiveerrors markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/wtfrecursiveerrors Sat, 09 Aug 2008 18:30:15 -0500
<![CDATA[ Christine in launchpad ]]> As the title says: Christine is now in lauchpad, the code in sourceforge.net si no longer maintained, the reason: I cannot commit my changes to the svn repo, then, I cannot share the newest code.

Christine is now a registered project in Launchpad, well, christine has been a in launchpad for a while but never really use it. So, I will use the launchpad christine account. The bug tracker, the code (and all the good things that launchpad offers) will be hosted here.

As part of the change, christine no longer use Subversion, instead, will use Bazaar, you can get the code using this:

bzr branch lp:christine

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Christineinlaunchpad markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Christineinlaunchpad Sun, 03 Aug 2008 11:00:41 -0500
<![CDATA[ Christine love in the night ]]>

Christine love in the night, originally uploaded by markuz.

1:47 in the morning. Im still giving some love to christine, that personal proyect that I used to code frequently. Now, it takes some days before I can toch it.

I'm working on the sqlite3 storage layer, This should help me with a more unified data between multiple "sources" that should be renamed as playlists. This will be usefull for many other features, I'm thinkin in some kind of browser.

Anyway, I'm still in the process. I'd like to share the code I have, but SourceForge.net's SVN service is bothering me with a 403 (Forbidden) error that don't let me commit my changes. Now I'm seriously change the project host. What do you recommend?

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Christineloveinthenight markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Christineloveinthenight Thu, 24 Jul 2008 02:03:57 -0500
<![CDATA[ GNOME 3.0 (Everything with tabs) == Suck! ]]> I believe that GNOME as a project is a very great project, event with the fact that they are reinveing the wheel from time to time (galeon, epiphany => epiphany webkit?). Anyway, I think it's great and as desktop is great too. I use GNOME in my every day and most of the time I'm quite happy, c'mon, there is no desktop environment that have everythin that every user could need.

I love most of the applications that GNOME has as desktop and many others that are not part of the Desktop but integrates well with it. I use such applications because they solve at least one of my problems, being something for my work or just my day to day computer use, and in most of the cases they solve that problem in a very good way, making me feel like I own my computer. But, I also think that they should evolve to be better.

In latest posts on http://planet.gnome.org/ I have seen several posts about some projects that want have tabs everywhere, which for me is ridiculous, Not every application must have tabs. One example is the totem at least not in the way Wouter Bolsterlee is showing it. Another application that I think should not is the calculator. Nautilus is nice for me because it may improve the user's workflow, but does anyone plays two items at the same time?.

Another UGLY example is what Davyd Madeley proposes to the GNOME panel, he may have some point while some people don't know "...what the little grey and blue boxes on their panel are for..." But the users are not stupid, they click them and will know that are they for. And.. a panel with tabs is just UGLY uses more space and useleses (I don't use the workspace switcher applet... is useles at least for me).

I Hope the GNOME developers reconsider where they should or not use tabs in the applications. And if they are going to do that.. Christian Neumair.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/GNOME30EverythingwithtabsSuck markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/GNOME30EverythingwithtabsSuck Sun, 13 Jul 2008 15:22:02 -0500
<![CDATA[ Christine importing a folder. ]]>

Christine importing a folder., originally uploaded by markuz.

I had worked on christine weeks ago, this week I had no time to give it some love. I have been using this "development" version (I think every version of christine is a development version) for a while.

Christine is faster at the load time, starting in just 4 seconds with at least 1500 items in the list, and the search and sort is quite fast too. But working with something like 6889 items in another 'source' I had make it a bit slow.

I think this is because christine use 3 models in the main list. Yes, three models. One is the main model, the one that holds all the library data. then the filter model and then the sort model. I'll try to make a model that implements in some way the filter and sort to reduce the work.

I notice that when you use a filter or even worse a filter and sort model ever time you select or move your cursor, or do anything with a row this process has to be done for every model you have. I mean, in christine you have to do it three times because of the three models. I think this sucks.

Well, I hope to have the time to write a bit on christine in this week.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Christineimportingafolder markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Christineimportingafolder Thu, 26 Jun 2008 23:31:30 -0500
<![CDATA[ What have I done in the last month ?? ]]> Well, as many of you know, this site, islascruz.org was "down", and I put down between quotes because wasn't really down, but, almost everybody uses islascruz.org and not islascruz.com, and that's ok. Anyway, islascruz.org is back again and I hope it never fails again.

Now, What have I done in the last month?, well, not blogging tongue.png . I have been using twitter but I had this need to post on my own site.

I had worked on christine, making it a little more usable, now,it loads in my computer in just a couple of seconds with a track list that is about 2600 rows, It uses a little less memory and I'm trying to make it better. But I'm working in some projects in the work (the paid work) and the idea to be working 8 hours in the office and get to the house to keep working isn't a very nice idea.

Christine in small view mode


dsc08103.jpgCristina and I get to the movies, we watch The Happening. Many people didn't like it, and I think this is because there is too much talk, too much death and almost no action. But the point in the movie is the message, we are hurting the planet, and we shouldn't. So, after the blablabla and the blood I like it, just by the message. We also watch Indiana Jones, and to be honest, I like it, but is not by far the most awesome movie I have seen.

As part of the "Leave the stress" activities cristina and I are doing, we are doing scented candles. We enjoy doing it, but the hard issue is cleaning the mess we do.

Well, I think I'm gonna leave this post here, my life is not that intersting. You should read somebody else personal posts..

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/WhathaveIdoneinthelastmonth markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/WhathaveIdoneinthelastmonth Thu, 19 Jun 2008 05:41:09 -0500
<![CDATA[ Creating a gtk custom model ]]> I have been working this week in a new custom model for one of the applications we are developing here at ICT Consulting. We found a problem with many many rows in gtk.ListStore. This is a common problem with Gtk's ListStore and TreeStore. Both are easy to implement and convenient if you are not going to work with too many values. I'm thinking in a couple of thousands. As far as this, the TreeModel is quite usable, but if you use a TreeFilterModel and/or TreeModelSort then you will experience some performance issues.

If what you want to do is just map the main application and then fill the model you can use the idle_add gobject function to iterate over your data and then store it in your model without freezing your application, but it is at the same way, the slowest. You can put chunks of 20 or so, then every time you application runs the callback function will run a small but faster insertion. Anyway, this is still a bit slow.

I have been doing tests with 100,000 rows, in the easy way there are just numbers using a for cycle via a range() result.I think in Gtk, the smaller is the data stored in the model, the faster it goes, because I can insert 100,000 rows in a gtk.ListStore in 7 seconds aprox. while in christine, inserting 2600 row in christine (with more data per cell) takes a lot more.

Anyway, the application that I'm developing shows a list of customers, this is a growing list as new customers are added, in our tests we need to show up to 17,000 customers. Using gtk.ListStore takes at least 17 seconds on my machine just to show it, but we also have a filter model becuse search in a list of 17000 items is not easy if you go looking every row by hand. So, usig the FilterModel takes almost the same time in searching something. Obviusly, waiting 17 seconds for the result is not an option, even worse, you made a mistake and wrote LOPEX instead LOPEZ.

So, I was searching over internet what can I do. I have already use the common 'tweaks' to improve the gtk.ListStore performance and I have reached the 8 - 9 seconds over those 17,000 items, but even with this, its too much time. The search points me to the gtk.GenericTreeModel. This generic model allows you to create a custom model where you can make your own tweaks to improve the performance of your model. In the link above gives you the way to use it. I have alreade created my own custom model and it really relly made the things better.

Now, one of the problems that gtk.GenericTreeModel have are the memory leaks. Using this model you may use lots of memory. This is because the GTM use to create a reference to the value that you are returning as Iter, e.g. you are using a list of lists, where you store the values, every item in the list is a row, then, the index if the iter wich references to the list you are storing in that row. The problem is that the GTM increase the reference count of you node (the list inside of the list) to aviod row destruction and then use the iter. This, in the best will make your values been refered until you destroy your model (and any reference to the data), in the worse the reference count of your data will never been unrefered and then the memory will never be freed.

You can use the invalidate_iters every time you modify the rows (add or delete) to make the rows invalid and then decrease the reference count of the row, and when your data have no more references then be deleted. But, I have the problem that the reference count was never decreased when I destroy the window or the model. Where is the trick here, use the Python's garbage collector, and your memory will be freed.

So, the new model based on PyGtk's GenericTreeModel actually works for us. Inserting 17,000 takes just 1 second, and the search (filter) is the same thing, 1 second is an option. I would like to see everything just appear when you request it, but one second is good for now. And testing with my current christine music list it takes just 0.06 seconds to show the list. Inserting 100,000 items (the easy way, just numbers) takes just 1.164 seconds to get filled with four columns and 2.36 seconds to show itself (creating a filter model and setting it to a treeview), so, for now this kind of optimizations will work for us, there are other optimizations on the Filter model and the treeview, My goal is to create something similar to wat Aaron bockover do with banshee.

Gtk Custom Model

Note: Test times are approximate, cache, cpu usage, load average and other may cause the times change, but at the end give us an idea of what is going on.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Creating-a-custom-model markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Creating-a-custom-model Sat, 17 May 2008 10:27:56 -0500
<![CDATA[ Testing the new christineConf module ]]>

Testing the new christineConf module, originally uploaded by markuz.

I have been working in the configuration module for christine, something similar to gconf, but just for christine. Why? well, many people complains because christine needs the gnome-extras package, where gconf is, and to be honest, christine didn't use all the gconf power, so, there isn't a big reaons to keep gconf on christine.

This isn't the only thing I have been working on. I'm trying to improve many things for the next release. Most of the work wil be in the list, zodman gives me some nice ideas, and I will try to implement them.

Anyway, you are also invited to work with me in the christine development. You can join the maling list for the next release.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/TestingthenewchristineConfmodule markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/TestingthenewchristineConfmodule Sat, 03 May 2008 23:58:14 -0500
<![CDATA[ Christine 0.1.6 ]]>
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:

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-016 markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-016 Tue, 29 Apr 2008 15:10:06 -0500
<![CDATA[ Nearshoring... The Movie! ]]>

]]> http://islascruz.org/html/index.php/Blog/SingleView/id/Nearshoring-The-Movie markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Nearshoring-The-Movie Fri, 18 Apr 2008 13:05:47 -0500 <![CDATA[ PyGTK y Threads ]]> 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.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/PyGTK-y-Threads markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/PyGTK-y-Threads Thu, 10 Apr 2008 18:51:44 -0500
<![CDATA[ Algo de amor para cristine ]]> 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

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Algo-de-amor-para-cristine markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Algo-de-amor-para-cristine Tue, 25 Mar 2008 16:50:02 -0500
<![CDATA[ Translation status ]]> It's nice to see that since yesterday to today there are already three new languages in the christine translations.

Translation status in christine

Wanna help? Translate christine HERE!

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Translation-status markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Translation-status Tue, 12 Feb 2008 16:57:22 -0600
<![CDATA[ christine 0.1.5 ]]> I have finally found a small time in my life to give a little love to christine and I'm not so proud (because of the delay) of the fifth revision of the fifth revision of the 0.1 version.

This fixes some bugs that I have found since the 0.1.4 but to be honest, I don't remember them. You can download the source packages from Here. There is also an Ubuntu Gutsy Package there.

christine 0.1.5

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/christine-015 markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/christine-015 Tue, 05 Feb 2008 15:34:41 -0600
<![CDATA[ Speed up gtk.ListStore ]]> 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.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Speed-up-gtkListStore markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Speed-up-gtkListStore Thu, 06 Dec 2007 15:24:50 -0600
<![CDATA[ Profiling Python ]]> Interesante articulo si te interesa ver que onda con los cuellos de botella de tu aplicacion en python: Profiling and Optimizing Python

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Profiling-Python markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Profiling-Python Thu, 22 Nov 2007 08:40:15 -0600
<![CDATA[ Widgets 'recortados' en Gtk ]]> 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

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Widgets-recordatos-en-Gtk markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Widgets-recordatos-en-Gtk Fri, 09 Nov 2007 17:59:37 -0600
<![CDATA[ Sockets ]]> 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.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Sockets markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Sockets Wed, 31 Oct 2007 18:22:09 -0500
<![CDATA[ Imprimir a un archivo PDF usando GTK. ]]> 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

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Imprimir-a-un-archivo-PDF-usando-GTK markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Imprimir-a-un-archivo-PDF-usando-GTK Fri, 19 Oct 2007 10:22:02 -0500
<![CDATA[ CakePHP + Scriptaculous ]]> He empezado a trabajar sobre cakephp y scriptaculous, por lo poco que he visto esta muy sencillo en el aspecto de casi no escribir nada. Ya veremos con que me salen despues face-smile.png
Cake + Scriptaculous

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/CakePHP--Scriptaculous markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/CakePHP--Scriptaculous Tue, 09 Oct 2007 12:40:14 -0500
<![CDATA[ Christine 0.1.1 ]]> 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.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-011 markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-011 Fri, 21 Sep 2007 14:10:38 -0500
<![CDATA[ Usando el widget creado anteriormente ]]> 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

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Usando-el-widget-creado-anteriormente markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Usando-el-widget-creado-anteriormente Fri, 14 Sep 2007 16:45:01 -0500
<![CDATA[ Un contenedor GTK Redimensionable al gusto. ]]> 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.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Un-contenedor-GTK-Redimensionable-al-gusto markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Un-contenedor-GTK-Redimensionable-al-gusto Thu, 13 Sep 2007 16:28:18 -0500
<![CDATA[ Respuesta ]]> 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.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Respuesta markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Respuesta Thu, 09 Aug 2007 15:38:02 -0500
<![CDATA[ Amo a PyGTK ]]> 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

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Amo-a-PyGTK markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Amo-a-PyGTK Wed, 08 Aug 2007 08:34:08 -0500
<![CDATA[ Christine 0.1 ]]> 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.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-01 markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-01 Sun, 29 Jul 2007 13:29:01 -0500
<![CDATA[ Christine for birthday! ]]> Bien, no es mi cumpleaños,pero lo va a ser en unos dias, Esta semana he estado trabajando en christine un poquito, el domingo y lunes en algunas partes experimtentales de christine, implementando csoas como Piratearle Metodos a un objeto para hacer empapelados y crear un ambiente de desarrollo mas sencillo. Todo esto es en lo que se esta trabajando y formará parte de christine.

Otras cosas en las que he trabajado es en bugfixes para la version 0.1 y pequeñas mejoras (que he de agregar lo otro). Lo mejor es que ahora christine tiene un mejor soporte para archivos m3u y pls y que tiene un "display" que ahora se dibuja con los colores del theme.

Christine

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-for-birthday markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-for-birthday Thu, 26 Jul 2007 12:56:34 -0500
<![CDATA[ "Piratearle" las propiedades a un objeto en Python ]]> Supon que tienes una clase Uno y quieres que obtenga las propiedades de la clase Dos o Tres, Por que harias esto?, simplemente porque en tu programa no quieres lidiar con

import uno,dos,tres
if "uno":
    refrerencia = uno()
elif "dos":
    referencia = dos()
else:
   referencia  = tres()
 

Y despues averiguar sobre quien haces la instancia en cada parte de tu codigo que requiera una instancia, de hecho, no es escalable, agregar una referencia mas seria doloroso si tu codigo es grande. mejor es hacer un empapelado de las referencias y hacer instancia a una sola, y que esta se haga pelotas de a quien referenciar.

Una forma de acercarse seria usar esto:

class wrapper:
    def __init__(self,modulo):
        moduloobj = __import__("paquete",globals(),locals(),[modulo])
        referencia = vars(moduloobj)[modulo]
        self.__empapelado = referencia()
 

Para obtener refrencias de las propiedades de un objeto usamos getattr, getattr recibe como primer parametro el objeto en el que se buscará la propiedad y como segundo, el nombre de la propiedad en cadena.

    def Query(self,metodo,*args):
        '''
        @param string metodo: Nombre del metodo en cadena
        @param *args: argumentos a pasar al metodo.
        '
''
        met = getattr(self.__empapelado,metodo)
        if callable(met):
            return met(*args) #ejecutamos el metodo y regresamos lo que nos regrese
 

Y tener:

a = wrapper("uno") #o "dos", o "tres"
a.Query("imprimeEsto","Texto a imprimir")

Esto, desde mi punto de vista es ideal, pues tu codigo es limpio, pero tal vez quieres hacer el empapelado sobre un proyecto que ya tiene rato jalando, y que todo se hace referencia a una clase, pero, quieres que esta clase ahora sea el "empapelado". Puedes Piratearle las propiedades a otro objeto, asi:

#!/usr/bin/env python

import paquete

class Pirata:
        '''
        Se piratea las propiedades de un objeto.
        '
''
        def __init__(self,modulo,objeto):
                '''
                Constructor
                '
''
                moduloobj = __import__(paquete,globals(),locals(),[modulo])
                referencia = vars(moduloobj)[modulo]
                pirateable = getattr(referencia,objeto)()
                for i in dir(pirateable):
                        newkey = i.replace("_%s_"%objeto,"_Pirata_")
                        self.__dict__[newkey] = getattr(pirateable,i)
 

Para tener algo asi:

a = test.Pirata("modulo","clase")
a.imprimeEsto("Texto a Imprimir")

De esta forma, no cambias nada en tu codigo que ya tienes, simplemente, en alguna parte de tu codigo, indicas que el "empapelado" ha de piratearle las propiedades a otro objeto que haga las operaciones necesarias.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Piratearle-las-propiedades-a-un-objeto-en-Python markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Piratearle-las-propiedades-a-un-objeto-en-Python Tue, 24 Jul 2007 11:58:34 -0500
<![CDATA[ Como dibujar un imagen (jpg, png, gif, etc..) en Cairo ]]> 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

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Como-dibujar-un-imagen-jpg-png-gif-etc-en-Cairo markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Como-dibujar-un-imagen-jpg-png-gif-etc-en-Cairo Sat, 21 Jul 2007 10:57:58 -0500
<![CDATA[ Creando tus propios objetos con gobject y error con las señales. ]]> En GTK+ es mu tipico crear widgets personalizados, o en un caso muy simple, agregar señales a tus funciones, no importa si dibujas algo o no. Bien, hay una forma de crear un objeto en Python y que te aparezca asi:

<nombredeObjecto object (paquete+modulo+nombredeObjeto) at 0xb7b6f34c&rt;

Pues es facil, en nuestra clase tendremos esto:

#notese que estoy haciendo una subclase de gtk.Widget.
class nombredeObjeto(gtk.Widget):
   def __init__(self):
       gobject.GObject.__init__(self)
       self.set_name("nombredeObjeto")

gobject.type_register(nombredeObjeto)

 

Asi de facil face-smile.png , el nombre que mostrara despues del "<" sera lo que definas en set_name

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Creando-tus-propios-objetos-con-gobject-y-error-con-las-seales markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Creando-tus-propios-objetos-con-gobject-y-error-con-las-seales Thu, 05 Jul 2007 12:38:50 -0500
<![CDATA[ Creando clases de Python en C ]]> Desfortunamente no encontre mucha documentacion, pero aqui va mas o menos como se hace. No encontre mucha documentacion sobre la implementacion de clases de Python en C, pero le seguiré buscando.

Algo que tambien me puse a buscarle hoy, fue como usar variables globales. es algo muy sencillo de lograr, algo que los programadores en C me diran, "Pues si, pendejo, asi se hace", pero yo no sabia, y alguien por ahi no sabrá tampoco, asi que ahi va:

suponiendo que tenemos un modulo demo, en python seria algo asi:

nombre = ""
apellido = ""

def asignaDatos(nom,ape);
    nombre = nom
    apellido = ape

def doSomething():
    print nombre
    print apellido

 

para poder usar algo asi:

Python 2.4.3 (#1, Jul 26 2006, 20:13:39)
[GCC 3.4.6] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import demo
>>> demo.asignaDatos("marco","islas")
>>> demo.doSomething()
marco
islas
>>>

en C seria asi:

#include <Python.h>
#include <stdio.h>
#include <stdlib.h>

struct pers {
    char *nombre;
    char *apellido;
};

struct pers persona;

static PyObject *doSomething(PyObject *self, PyObject *args){
    extern struct pers persona;
    printf("%s\n",persona.nombre);
    printf("%s\n",persona.apellido);
    free(persona.nombre);
    free(persona.apellido);
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *asignaDatos(PyObject *self, PyObject *args){
    extern struct pers persona;
    char *nombre,*apellido;
    persona.nombre = malloc (1024);
    persona.apellido = malloc(1024);
    PyArg_ParseTuple(args,"ss",&nombre,&apellido);
    strcpy(persona.nombre,nombre);
    strcpy(persona.apellido,apellido);
    Py_INCREF(Py_None);
    return Py_None;
}

static PyMethodDef demoMethods[] = {
    {"doSomething",doSomething,METH_VARARGS,"imprime los valores de la persona"},
    {"asignaDatos",asignaDatos,METH_VARARGS,"Asigna los datos de la persona en la estructura"},
};

PyMODINIT_FUNC initdemo(void){
    (void) Py_InitModule("demo",demoMethods);
}

 

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Creando-clases-de-Python-en-C markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Creando-clases-de-Python-en-C Thu, 05 Jul 2007 16:26:37 -0500
<![CDATA[ Christine 0.1rc2.deb ]]> nibblesmx ha creado un paquetin para Ubuntu Feisty de Christine 0.1.rc2. Puedes obtenerlo aqui

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-01rc2deb markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-01rc2deb Wed, 04 Jul 2007 13:01:43 -0500
<![CDATA[ Work and Fun! ]]> Asi es, he tenido algo de trabajo en esta semana, primero que nada, quiero pedir una disculpa al Grupo de usuarios de software libre de Poza Rica (GNUPR) por no haber podido asistir a las tres ultimas reuniones, me fue imposible, la primera, andaba en salamanca en ICTC, y las otras dos por motivos personales, espero en estas semanas compensar.

Como ya lo mencioné en el post anterior, he estado usando Eclipse por un ratito, no saben lo facil que me ha hecho desarrollar en Python con el plugin PyDev, ojo, aun no uso las PyDev extensions, pero puede que en un rato pague la licencia, dependiendo de que tan bien me sienta en un futuro.

Que es lo bueno?, bien, pues el debugger me ayuda algo, pero el autocompletado, el docstring, el hecho de que analiza mi codigo en el vuelo y me dice si tengo algun error de sintaxis, el crear un modulo o un paquete me queda a un click, el navegador me muestra mis modulos, sus clases y propiedades sean publicas o "privadas". Es un buen chunche muy bonito, muy practico. Ademas, en ICTC usamos svn para manejar las revisiones del software, asi que use el subclipse (el plugin de tigris.org para manejar subversion en eclipse) y todo va sweet, incluso el hecho de que no se hace autenticacion por contraseña sino por llave dsa, muy bonito.

Tambien he estado utilizando Tomboy para mis notas, ya me estoy acostumbrando a usarlo face-smile.png .

En la semana me fui a Huauchinango a renovar mi licencia de manejo, no tengo fotos porque se me olvido la camara (junto con mi celular) en la casa, pero me di cuenta de algo genial, las oficinas de MySpace.com en mexico han cerrado o se han reubicado puesto que el local esta en renta. En cuanto vaya de nuevo, tomare foto a lo que eran las "oficinas".

Creo que es todo por ahora.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Work-and-Fun markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Work-and-Fun Sat, 23 Jun 2007 23:44:40 -0500
<![CDATA[ usando Eclipse ]]> Quienes me conoces bien saben que soy vimero de corazón, no lo puedo evitar, simplemente me parece perfecto que en vim tenga muchas de las opciones que necesito, y como normalmente me concentro en un par de archivos, pues... con las funciones split y vsplit me siento super bien.

Ahora que estuve en Slamanca Aldo me comento del autocompletado en vim, usando Ctrl+P aparece un "popup" o menu desplegable con las ocurrencias, usando Ctrl+P se selecciona entre las ocurrencias. Una razon mas para seguir usando vim.

Aldo es usuario de vim tambien, pero para pogramar en Python usa eric3. Hace un par de años cuando empezaba a programar en Python lo use un poco (tambien usaba ubuntu) pero poco me duro ubuntu en la maquina y menos me duro eric3. Lo sentia feo, en cierta forma incomodo.

La semana pasada me compile lo necesario y eche a andar eric3 en la cususa, me gusto mucho, bastante practico, pero debo decir que no perfecto y si bien cumple con muchas de mis espectativas, no me siento tan comodo con el. Asi que me puse a probar con Eclipse, cierto, ya me lo dijo aldo, que soy un extremista, de usar vim a Eclipse, pero eclipse con pydev es la neta, me gusto mucho, y creo que para desarrollar con python lo seguire usando un rato mas, si es que no me harto.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/usando-Eclipse markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/usando-Eclipse Thu, 14 Jun 2007 19:28:48 -0500
<![CDATA[ Cambiando el color de nuestros widgets en GTK. ]]> 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.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Cambiando-el-color-de-nuestros-widgets-en-GTK markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Cambiando-el-color-de-nuestros-widgets-en-GTK Fri, 08 Jun 2007 13:16:00 -0500
<![CDATA[ Christine 0.1rc2 ]]> Otro release candidate para la 0.1 face-smile.png esta vez el release candidate 2, se han corregido unos errores menores y un pequeño bug que provocaba que la funcion de busqueda no hiciera nada despues de importar algun archivo.

christine-0.1rc2.tar.bz2

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-01rc2 markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-01rc2 Mon, 04 Jun 2007 19:56:30 -0500
<![CDATA[ Christine 0.1rc1 ]]> 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

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-01rc1 markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Christine-01rc1 Fri, 01 Jun 2007 16:26:59 -0500
<![CDATA[ Evitando que las aplicaciones en GTK se congelen... ]]> ... 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.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Evitando-que-las-aplicaciones-en-GTK-se-congelen markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Evitando-que-las-aplicaciones-en-GTK-se-congelen Fri, 18 May 2007 11:03:20 -0500
<![CDATA[ Importing files in christine. ]]> Today I have work in the import stuff in christine, since we start working on it we have several issues, some crashes of freezes. Most of them in some other computers. In my computer there where just some freezes that get solved just in time, i mean, I have to be wait a bit and chritine updates itself.

In the first aproach I try to use gobject.timeout_add to iterate over the files to import, that wasn't the right approach, because, the time between insert and insert where fixed, 0.6 secs, no matter if you have a 4 CuadCore CPU's it will take the same time in my machine. And in some old machines, this just crash. And it crash because in that machines we have to wait a bit more before insert another file to be parsed.

The other (the right)) approach was using signals. The main library was emitting signals when it was ready to accept another file to be inserted, but there where something that just crashes my app, I try to use this with threads, timer from gobject and nothing. At this time, it just don't crash, but it just freeze.

Answer.... Use this:

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

 

Just, let GTK to update the interface before doing anything else. face-smile.png . Now it 's sweet and it takes 5 to 6 minutes to import my ~2500 files, takes more importing mp3 than ogg, but that's a gstreamer issue.

Importing media to christine

Update1 For some weird reasons this seems not working in some computers. It doesn't run well in nibblesmx machine, even that I guess it's faster than mine and uses a OS that is compiled for i686 instead i486 (wich makes no big difference). The sema with n0sferatu, but I think that is the gstreamer version that they have or something like that, because both of them use Ubuntu... Some ubuntu user to thest the code of christine?.

]]>
http://islascruz.org/html/index.php/Blog/SingleView/id/Importing-files-in-christine markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/Blog/SingleView/id/Importing-files-in-christine Wed, 16 May 2007 22:15:22 -0500
<![CDATA[ Sin que decir. ]]> Esta semana ha sido muy poco productiva para mi, no tengo mucho que decir.

  • Sigo traba