Mostrando las entradas con la etiqueta gtk. Mostrar todas las entradas
Mostrando las entradas con la etiqueta gtk. Mostrar todas las entradas

viernes, octubre 29, 2010

Como generar archivos .exe e instaladores para una aplicación python (y pygtk)

Como generar archivos .exe e instaladores para una aplicación python


Este documento describe los pasos necesarios para crear un archivo ejecutable
de una aplicación python y como generar un instalador y una versión portable
para dicha instalación.

Este documento asume que la aplicación se basa en GTK pero debería funcionar
con menores cambios en otros toolkits.

porque un instalador

  • se requiere instalar muchos componentes a mano por el usuario final para una sola aplicación
  • muchos instaladores pequeños
  • difíciles de encontrar
  • difícil encontrar las versiones exactas que funcionan en conjunto
  • requiere instalarlos en un orden definido
  • rezar
  • algunas veces incluso haciendo todo bien puede no funcionar
  • fácil de automatizar y documentar para replicar con cada nueva versión
  • liberar al usuario final de los problemas para poder usar la aplicación

componentes requeridos

  • python
  • todas las librerías utilizadas por la aplicación
  • py2exe
  • nsis
  • tiempo y suerte

orden de instalación

algunos instaladores son independientes de otros, pero para evitar posibles problemas recomiendo la instalación en el siguiente orden.

  • python
  • gtk-runtime
  • gtk2-themes
  • nsis
  • pygobject
  • pycairo
  • pygtk
  • pywin32
  • py2exe

tareas extra

  • setear la variable de entorno PATH para agregar el path a la instalación de python
  • probar la instalación con una pequeña aplicación gtk
>>> import gtk
>>> w = gtk.Window()
>>> l = gtk.Label("asd")
>>> w.add(l)
>>> w.show_all()
>>> gtk.main()

prueba con una aplicación de ejemplo

Cree un repositorio con una aplicación de ejemplo para probar los pasos, la aplicación esta disponible en github acá:

http://github.com/marianoguerra/PyGtkOnWindows

pasos

  • descargarla
  • descomprimirla
  • ejecutar python setup.py py2exe
  • copiar los directorios lib y share de la instalación del runtime de gtk (no de la instalación de pygtk) al directorio dist
  • copiar todos los archivos del directorio dll al directorio dist
  • borrar los locales y temas no usados de los directorios copiados a dist (yo solo dejo el theme MS-Windows)
  • crear la siguiente estructura de directorios dentro de dist: etc/gtk-2.0
  • dentro de ese directorio crear un archivo llamado gtkrc con una linea como la siguiente dentro:
    • gtk-theme-name = "MS-Windows"
    • podes cambiar el tema usado manteniendo otro theme dentro de share/themes y cambiando el nombre del theme en gtkrc
  • right click en ejemplo.nsi y seleccionar "Compile NSIS Script"
  • right click en ejemplo-portable.nsi y seleccionar "Compile NSIS Script"
  • deberías tener el instalador y la versión portable disponibles
  • para probar que funciona correctamente, correr el instalador y la versión portable en una instalación de windows sin los paquetes que instalaste anteriormente

probar con una aplicación real

ahora para sentirlo mas real, creemos un instalador y una versión portable de
un programa real, en este caso, un proyecto personal llamado emesene 2
(http://www.emesene.org/).

pasos

  • descargarlo de http://github.com/emesene/emesene
  • descomprimirlo
  • copiar setup.py and ez_setup.py al directorio emesene
  • cd emesene
  • correr python setup.py py2exe
  • cd ..
  • copiar los directorios lib y share de la instalación del runtime de gtk (no de la instalación de pygtk) al directorio dist
  • copiar todos los archivos del directorio dll al directorio dist
  • borrar los locales y temas no usados de los directorios copiados a dist (yo solo dejo el theme MS-Windows)
  • crear la siguiente estructura de directorios dentro de dist: etc/gtk-2.0
  • dentro de ese directorio crear un archivo llamado gtkrc con una linea como la siguiente dentro:
    • gtk-theme-name = "MS-Windows"
    • podes cambiar el tema usado manteniendo otro theme dentro de share/themes y cambiando el nombre del theme en gtkrc
  • right click en emesene.nsi y seleccionar "Compile NSIS Script"
  • right click en emesene-portable.nsi y seleccionar "Compile NSIS Script"
  • deberías tener el instalador y la versión portable disponibles
  • para probar que funciona correctamente, correr el instalador y la versión portable en una instalación de windows sin los paquetes que instalaste anteriormente

notas

[EN] How to generate .exe files and installers for a python (and pygtk) applications

How to generate .exe files and installers for a python applications


This document describes the steps required to create an executable file from a
python program and how to build an installer and portable file from that
application.


The document assumes that the application is based on GTK but it should work
with minor changes for other toolkits.

why an installer

  • many components are required to install by hand by the end user for a simple application
  • a lot of small installers
  • hard to find
  • hard to match the exact versions that work together
  • install them in the required order
  • pray
  • sometimes even doing everything right it may not work
  • easy to automate and document to replicate with each new version
  • free the end user from problems to use the app

required components

  • python
  • all the libraries used by the application
  • py2exe
  • nsis
  • time and luck ;)

installation order


some installers are independent from the others, but to avoid posible problems I recommend the installation in this order.

  • python
  • gtk-runtime
  • gtk2-themes
  • nsis
  • pygobject
  • pycairo
  • pygtk
  • pywin32
  • py2exe

extra tasks

  • set the PATH environment variable to add the path to the python installation
  • test that the installation works with a simple gtk application
>>> import gtk

>>> w = gtk.Window()
>>> l = gtk.Label("asd")
>>> w.add(l)
>>> w.show_all()
>>> gtk.main()

test with a sample application


I created a repository with a sample application to test the steps, the application is available in github here:

http://github.com/marianoguerra/PyGtkOnWindows

steps

  • download it
  • unpack it
  • run python setup.py py2exe
  • copy the lib and share directory from the gtk runtime installation (not the pygtk installation) to the dist directory
  • copy all the files from the dll directory to the dist directory
  • remove unused locales and unused themes (I keep only ms theme)
  • create the following dirs inside dist: etc/gtk-2.0
  • inside that create a file called gtkrc with a line like this inside:
    • gtk-theme-name = "MS-Windows"
    • you can change the theme by keeping that theme inside share/themes and changing the name in gtkrc
  • right click on ejemplo.nsi and select "Compile NSIS Script"
  • right click on ejemplo-portable.nsi and select "Compile NSIS Script"
  • you should have the installer and portable versions available
  • to test that it works correctly, run the installer and portable versions in a windows installation without the packages you installed previously

test with a real application

now to make it feel more real let's create an installer and portable versions
for a real world program, in this case, a project of mine called emesene 2
(http://www.emesene.org/).

steps


  • download it from http://github.com/emesene/emesene
  • unpack it
  • copy setup.py and ez_setup.py to the emesene directory
  • cd to emesene
  • run python setup.py py2exe
  • cd ..
  • copy the lib and share directory from the gtk runtime installation (not the pygtk installation) to the dist directory
  • copy all the files from the dll directory to the dist directory
  • remove unused locales and unused themes (I keep only ms theme)
  • create the following dirs inside dist: etc/gtk-2.0
  • inside that create a file called gtkrc with a line like this inside:
    • gtk-theme-name = "MS-Windows"
    • you can change the theme by keeping that theme inside share/themes and changing the name in gtkrc
  • right click on emesene.nsi and select "Compile NSIS Script"
  • right click on emesene-portable.nsi and select "Compile NSIS Script"
  • you should have the installer and portable versions available
  • to test that it works correctly, run the installer and portable versions in a windows installation without the packages you installed previously

notes

jueves, junio 03, 2010

webshots - a.k.a. ya tendria que empezar a trabajar :P

y si, esto de estar recibido y a la espera del día que entre a mi nuevo trabajo (solo 15 faltan dias) me da bastante tiempo libre para probar todas esas cosas que cuando estudiaba o trabajaba quedaban "para después".

En este caso necesitaba una herramienta para transformar mis presentaciones hechas con pepete a un formato que pueda ser distribuido offline.

pensé dos cosas, bajarlo a imágenes o a pdfs y como no me decidía hice las dos.

El resultado es webshot, quizás le sea útil a alguien, quizás no, que importa, el código esta ahí :D.

webshot es un webkit adentro de una ventana gtk que tiene algunos bindings útiles como ir a fullscreen, guardar la porción visible de la pantalla a png o pdf y no mucho mas.

esta herramienta me permite dar las presentaciones de pepete con un visor limpio, poder ir a fullscreen y volver y si quiero transformar las presentaciones en pdf simplemente saco screenshot de cada slide y luego los junto.

mostrar un screenshot de webshot es lo mismo que mirar tu browser actual así que mucho sentido no tiene, eso si, hay dos ejemplos del resultado de guardar la pagina en el proyecto:

la pagina del proyecto en pdf

la pagina del proyecto en png

una presentación sobre webshot en pepete (te recomiendo abrirla en webshot :P)

http://marianoguerra.github.com/pepete/show.html#webshot.json
eso es todo

viernes, noviembre 20, 2009

Browser en pygtk con webkit en unas cuantas lineas de codigo


import sys
import gtk
# https://bugs.launchpad.net/bugs/480398
gtk.gdk.threads_init()
import webkit

class Browser(gtk.Window):
def __init__(self, url=''):
gtk.Window.__init__(self)
self.set_title('Browser')
self.set_default_size(640, 480)

self.url = url

scroll = gtk.ScrolledWindow()
scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
scroll.set_shadow_type(gtk.SHADOW_IN)

self.view = webkit.WebView()
scroll.add(self.view)

vbox = gtk.VBox()

entry = gtk.Entry()
entry.connect('activate', self._on_url_changed)

if self.url:
entry.set_text(self.url)
entry.activate()

vbox.pack_start(entry, False)
vbox.pack_start(scroll, True, True)
vbox.show_all()

self.add(vbox)

self.connect('delete-event', lambda *args: sys.exit(0))

def _on_url_changed(self, entry):
'''called when the url changes'''
self.url = entry.get_text()

if not self.url.startswith('http://') and not self.url.startswith('https://'):
self.url = 'http://' + self.url

self.view.open(self.url)

if __name__ == '__main__':
browser = Browser('www.google.com')
browser.show()
gtk.main()

sábado, abril 18, 2009

problemas de pynotify con threads y gtk

agregue soporte para notificaciones en emesene 2, y de pronto la gui se empezó a congelar (la aplicación no porque se podía ver el log del protocolo que seguía pasando). Me di cuenta muy de suerte que el problema eran las notificaciones (había metido muchos otros cambios) ya que en debian no tenia python-notify instalado y andaba sin problemas y en ubuntu se congelaba, instale python-notify y se empezó a congelar de nuevo.

comente las lineas y andaba, por lo que era eso.. busque en google y vi un parche que en lugar de:

gtk.gdk.threads_init()

hacia:

gobject.threads_init()
gtk.gdk.threads_init()

probe con eso y salio con fritas.

este post es por si algún día les pasa algo parecido no tengan que pelear un buen rato para ver donde estaba el problema.

lunes, noviembre 12, 2007

Codeando al pedo..

Debido a mi estadía en Alemania, me veo forzado a traducir un montón de palabras de alemán a español, para ello uso el servicio de esta pagina:

www.myjmk.com

pero como la interfaz es bastante bloated, decidí hacer un programita simple que saciara mis apetencias de traducción, en un rato, salio lo siguiente:

peleando un poco con los encodings, hice unos cuantos requests y de pronto, dejo de funcionar, no parecía haber ningún error, debugee lo que me estaba mandando el programa, y leo el siguiente lindo mensaje:

Access not allowed.

Your access to the dictionary was rated as invalid. This could have various reasons. Possibly there is some other user sharing some ressources with you (e.g. a web proxy of your provider), scanning our dictionary systematically. We are very sorry for the inconvenience.

bue, tendrá que ser de otra forma :P

pero bueno, aprendí algunas cositas

  • use por primera vez super(), enumerate() y zip() [1]
  • conoci ' '.join()[2] en lugar de import string; string.join()[3]
  • conoci s.partition('sep')[4]
[1] http://docs.python.org/lib/built-in-funcs.html
[2] http://docs.python.org/lib/string-methods.html#l2h-250
[3] http://docs.python.org/lib/node42.html#l2h-379
[4] http://docs.python.org/lib/string-methods.html#l2h-254

jueves, febrero 22, 2007

snippet?

38 lineas de codigo..
para una minicompetencia

import sys, gtk, time, random
l = c = m = 10
def onMinaPressed( button, x , y, campo ):
if campo[ 'minas' ][ x ][ y ] == True:
print 'Perdiste'
sys.exit( 0 )
else:
button.set_label( str( campo[ 'numeros' ][ x ][ y ] ) )

def getCampo( filas = 10, columnas = 10, minas = 10 ):
l = [ [ 0 for x in range( columnas ) ] for y in range( filas ) ]
m = [ [ False for x in range( columnas ) ] for y in range( filas ) ]
for x in range( minas ):
(x , y) = ( random.randint( 0, columnas - 1 ), random.randint( 0, filas - 1 ) )
while m[ y ][ x ] != False:
(x , y) = ( random.randint( 0, columnas - 1 ), random.randint( 0, filas - 1 ) )
m[ y ][ x ] = True
for i in range( -1,1 ):
for j in range( -1,1 ):
l[ x + i ][ y + j ] += 1
return { 'numeros' : l, 'minas' : m }

campo = getCampo( l, c, m )
w = gtk.Window()
w.set_title( 'HKmine' )
w.set_default_size( l * 15, c * 15 )
w.connect( 'delete-event', lambda *l: sys.exit( -1 ) )
v = gtk.VBox()
for y in range( l ):
h = gtk.HBox()
for x in range( c ):
b = gtk.Button( ' ' )
b.connect( 'clicked', onMinaPressed, x, y, campo )
h.pack_start( b )
v.pack_start( h )
w.add( v )
w.show_all()
gtk.main()



si, ahora vienen todos esos comentarios del tipo sos un **** ...

Seguidores

Archivo del Blog