2011-10-25 11 views
11

Estoy usando Python 2.6 y PyGTK 2.22.6 desde el all-in-one installer en Windows XP, intentando crear un archivo ejecutable de un solo archivo (a través de py2exe) para mi aplicación.Agrupar recursos GTK con py2exe

Mi problema es que cuando ejecuto mi aplicación como un script (es decir. No se construye en un archivo .exe, así como un conjunto disperso de .py archivos), que utiliza el tema de aspecto nativa de Windows, pero cuando ejecuto el built exe Veo el tema GTK predeterminado.

Sé que este problema se puede solucionar copiando un montón de archivos en el directorio dist creado por py2exe, pero todo lo que he leído implica copiar manualmente los datos, pero quiero que esto sea una parte automática de la compilación proceso. Además, todo lo relacionado con el tema (incluido the FAQ) está desactualizado - PyGTK ahora mantiene sus archivos en C:\Python2x\Lib\site-packages\gtk-2.0\runtime\..., y simplemente copiar los directorios lib y etc no soluciona el problema.

Mis preguntas son:

  1. Me gustaría ser capaz de encontrar mediante programación los datos de tiempo de ejecución de GTK en setup.py en lugar de caminos de codificación duros. ¿Cómo hago esto?

  2. ¿Cuáles son los recursos mínimos que necesito incluir?

Actualización: pude haber respondido casi # 2 por ensayo y error. (. Es decir, MS Windows) para el "pelele" tema a trabajar, necesito los archivos de:

runtime\lib\gtk-2.0\2.10.0\engines\libwimp.dll 
runtime\etc\gtk-2.0\gtkrc 
runtime\share\icons\* 
runtime\share\themes\MS-Windows 

... sin el prefijo runtime, pero por lo demás con la misma estructura de directorios, sentado directamente en el directorio dist producido por py2exe. Pero, ¿de dónde viene el 2.10.0, dado que gtk.gtk_version es (2,22,0)?

Respuesta

9

Respondiendo a mi propia pregunta aquí, pero si alguien sabe, no dude en responder también. Algunos de ellos parecen bastante frágiles (por ejemplo, los números de versión en las rutas), así que coméntelos o edítelos si conoce una forma mejor.

1. Encontrar los archivos

En primer lugar, utiliza este código para encontrar realmente la raíz del tiempo de ejecución de GTK. Esto es muy específico a la forma de instalar el tiempo de ejecución, sin embargo, y probablemente podría mejorarse con una serie de comprobaciones para lugares comunes:

#gtk file inclusion 
import gtk 
# The runtime dir is in the same directory as the module: 
GTK_RUNTIME_DIR = os.path.join(
    os.path.split(os.path.dirname(gtk.__file__))[0], "runtime") 

assert os.path.exists(GTK_RUNTIME_DIR), "Cannot find GTK runtime data" 

2. ¿Qué archivos que incluyen

Esto depende de (a) qué tan grande es el tamaño de una preocupación, y (b) el contexto de la implementación de su aplicación. Con eso quiero decir, ¿lo está implementando en todo el mundo en el que cualquiera puede tener una configuración regional arbitraria, o es solo para uso corporativo interno donde no necesita cadenas de acciones traducidas?

Si desea que Windows tematización, tendrá que incluir:

GTK_THEME_DEFAULT = os.path.join("share", "themes", "Default") 
GTK_THEME_WINDOWS = os.path.join("share", "themes", "MS-Windows") 
GTK_GTKRC_DIR = os.path.join("etc", "gtk-2.0") 
GTK_GTKRC = "gtkrc" 
GTK_WIMP_DIR = os.path.join("lib", "gtk-2.0", "2.10.0", "engines") 
GTK_WIMP_DLL = "libwimp.dll" 

Si desea que los iconos de Tango:

GTK_ICONS = os.path.join("share", "icons") 

También hay datos de localización (que omito, pero puede que no desee):

GTK_LOCALE_DATA = os.path.join("share", "locale") 

3. Uniendo juntos

En primer lugar, esta es una función que recorre el árbol del sistema de archivos en un punto determinado y produce una salida adecuada para la opción data_files.

def generate_data_files(prefix, tree, file_filter=None): 
    """ 
    Walk the filesystem starting at "prefix" + "tree", producing a list of files 
    suitable for the data_files option to setup(). The prefix will be omitted 
    from the path given to setup(). For example, if you have 

     C:\Python26\Lib\site-packages\gtk-2.0\runtime\etc\... 

    ...and you want your "dist\" dir to contain "etc\..." as a subdirectory, 
    invoke the function as 

     generate_data_files(
      r"C:\Python26\Lib\site-packages\gtk-2.0\runtime", 
      r"etc") 

    If, instead, you want it to contain "runtime\etc\..." use: 

     generate_data_files(
      r"C:\Python26\Lib\site-packages\gtk-2.0", 
      r"runtime\etc") 

    Empty directories are omitted. 

    file_filter(root, fl) is an optional function called with a containing 
    directory and filename of each file. If it returns False, the file is 
    omitted from the results. 
    """ 
    data_files = [] 
    for root, dirs, files in os.walk(os.path.join(prefix, tree)):   
     to_dir = os.path.relpath(root, prefix) 

     if file_filter is not None: 
      file_iter = (fl for fl in files if file_filter(root, fl)) 
     else: 
      file_iter = files 

     data_files.append((to_dir, [os.path.join(root, fl) for fl in file_iter])) 

    non_empties = [(to, fro) for (to, fro) in data_files if fro] 

    return non_empties 

Así que ahora puede llamar setup() así:

setup(
    # Other setup args here... 

    data_files = (
        # Use the function above... 
        generate_data_files(GTK_RUNTIME_DIR, GTK_THEME_DEFAULT) + 
        generate_data_files(GTK_RUNTIME_DIR, GTK_THEME_WINDOWS) + 
        generate_data_files(GTK_RUNTIME_DIR, GTK_ICONS) + 

        # ...or include single files manually 
        [ 
         (GTK_GTKRC_DIR, [ 
          os.path.join(GTK_RUNTIME_DIR, 
           GTK_GTKRC_DIR, 
           GTK_GTKRC) 
         ]), 

         (GTK_WIMP_DIR, [ 
          os.path.join(
           GTK_RUNTIME_DIR, 
           GTK_WIMP_DIR, 
           GTK_WIMP_DLL) 
         ]) 
        ] 
       ) 
)