2012-01-15 5 views
8

Tengo un problema con pyinstaller al agregar algunos archivos de datos como imágenes y txts al programa Python. Por ejemplo, he creado una barra de herramientas con íconos, y los almaceno en una carpeta separada llamada imágenes. También tengo algunos archivos txt y xml para almacenar algunas configuraciones. Estos archivos txt ant xml se almacenan en otra carpeta llamada data_files. Todos los archivos py se almacenan en otra carpeta llamada source.Construir imágenes y algunos archivos de configuración como archivos txt y xml con pyinstaller

Cuando intento crear este programa python con pyinstaller, pyinstaller puede construir correctamente toda la carpeta de origen, pero las carpetas images y data_files no pueden compilarse. Revisé la documentación de pyinstaller pero no pude encontrar ninguna solución. He realizado muchas búsquedas en Google y he encontrado que el único recurso this es útil, pero este es un recurso muy inadecuado.

Mi pregunta principal es: ¿cómo puedo construir un archivo exe con una carpeta construida por separado, como imágenes y confs, usando el instalador de pizarras?

Edit: Encontré la solución. Cuando crea el archivo de especificación, tiene que a.datas parámetro.

# -*- mode: python -*- 
a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), '/home/vmode/Desktop/derlem2/sources/TextSTAT.py'], 
      pathex=['/home/pyinstaller']) 
a.datas += [("Images/New.gif","/home/vmode/Desktop/derlem2/Images/New.gif","DATA")] 
a.datas += [("Images/Open.gif","/home/vmode/Desktop/derlem2/Images/Open.gif","DATA")] 
a.datas += [("Images/Column.gif","/home/vmode/Desktop/derlem2/Images/Column.gif","DATA")] 
pyz = PYZ(a.pure) 
exe = EXE(pyz, 
      a.scripts, 
      a.binaries, 
      a.zipfiles, 
      a.datas, 
      name=os.path.join('dist', 'TextSTAT'), 
      debug=False, 
      strip=False, 
      upx=True, 
      console=1) 

El código de especificación anterior está diseñado para mi proyecto. Como se ve en este código de especificación, he incluido 3 iconos para compilar con el programa python. Cuando se genera el programa, hay un archivo ejecutable independiente con estos iconos incrustados.

Pero, ¿y si tenemos tantos archivos? Supongamos que tenemos 1000 iconos para usar en nuestro programa. Es muy inadecuado escribir a mano el archivo de especificaciones. Debe haber un sistema de bucle para leer el directorio de archivos y agregar estos archivos dinámicamente. Pero no pude encontrar cómo agregar estos archivos dinámicamente. No hay ninguna posibilidad de agregar tantos archivos a mano, creo. Si alguien sabe, por favor comparta.

+0

Pruebe 'cx_freeze'. Intenté 'py2exe',' pyinstaller', algún otro programa aleatorio, y solo 'cx_freeze' funcionó para mí (utilicé PyQt4). Si desea ver mi código para hacer un binario, está en GitHub: https://github.com/Blender3D/Bindery/blob/master/tools/binary.py – Blender

+0

Gracias por su interés. Pero cx_freeze solo crea el archivo .exe. Quiero construir el programa siguiendo todas las plataformas. Entonces tengo que usar el instalador de pizarras. Pero tengo algunos grandes toubles. – user1150508

+0

No, 'cx_freeze' crea binarios para Linux también. Mac requiere Py2app. – Blender

Respuesta

5

Al crear mi ejecutable, me encontré con este problema también. Como el archivo .spec está usando python, el módulo glob fue mi solución.

imagesList = [] 
imagesList.append(('icon.ico', '..\\pathfinder\\icon.ico', 'DATA')) 
import glob 
allImages = glob.glob('..\\pathfinder\\*.png') 
for eachImage in allImages: 
    imageParts = eachImage.split('\\') 
    imagesList.append((imageParts[-1], eachImage, 'DATA')) 
print imagesList 
a.datas += imagesList 

La línea 2 con respecto a icon.ico era separada porque tenía una extensión de archivo diferente y, por lo tanto, puede ser excluida. '.. \ pathfinder' es la ruta para todos los archivos de mi programa (relativos desde el directorio de pyinstaller). glob busca en el directorio todos los archivos .png (tengo 65 y me negué a escribirlos todos a mano) y devuelvo una lista de ellos como cadenas, el directorio relativo completo está intacto. Para separarlo en una lista de nombres de archivo, utilicé string.split() en la barra invertida. Luego, para cada una, anexe a una lista hecha por el usuario una tupla de la parte final de la división de cadena (que terminaría siendo solo el nombre de archivo de la imagen) y la ruta completa. Finalmente, con una lista de todos los archivos, agréguelos a a.datas.

He confirmado a través de la línea de comandos que esto realmente funciona correctamente, y puede volver a copiar el bucle para cualquier extensión de archivo adicional.

Desafortunadamente, a pesar de que parece extraer y adjuntar los nombres de archivo correctamente, mi ejecutable todavía no parece ser creado con los archivos (o el ejecutable no puede encontrar los archivos dentro de sus propios datos) y todavía tengo que tener el imágenes en bruto en el mismo directorio para que funcione; tal vez tengo los elementos de la tupla ordenados incorrectamente (y por lo tanto, si es así, debe ajustar mi código en consecuencia). Afortunadamente, esta carga dinámica aún funcionará para ti, sin embargo. imageParts [-1] representa el nombre de cada archivo .png, y cada imagen representa su ruta completa (o ruta relativa si eso es lo que se usó en glob).

1

Si todas las imágenes se muestran bajo mismo directorio puede utilizar Árbol

dict_tree = Tree('/home/vmode/Desktop/derlem2/Images', prefix = 'Images') 
a.datas += dict_tree 
Cuestiones relacionadas