2012-01-15 11 views
8

Ho un problema con pyinstaller quando aggiungo alcuni file di dati come immagini e txts al programma python. Ad esempio, ho creato una barra degli strumenti con icone e li memorizzo in una cartella separata denominata immagini. Inoltre ho alcuni file txt e xml per memorizzare alcune configurazioni. Questi file xml di txt ant sono memorizzati in un'altra cartella denominata data_files. Tutti i file py sono memorizzati in un'altra cartella denominata fonte.Costruisci immagini e alcuni file di configurazione come i file txt e xml con pyinstaller

Quando sto provando a creare questo programma python con pyinstaller, pyinstaller può compilare con successo tutta la cartella sorgente, ma le cartelle images e data_files non possono essere create. Ho controllato la documentazione di pyinstaller ma non ho trovato nessuna soluzione. Ho fatto un sacco di ricerche su google e ho trovato solo il ricorso allo this come risorsa, ma questa è una risorsa molto inadeguata.

La mia domanda principale è: come posso creare un file exe con una cartella costruita separatamente come immagini e conf con pyinstaller?

Modifica: Ho trovato la soluzione. Quando si crea il file spec è necessario il parametro a.datas.

# -*- 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) 

Il codice specifica di cui sopra è stato progettato per il mio progetto. Come visto in questo codice spec ho incluso 3 icone da compilare con il programma python. Quando il programma viene generato, c'è un file eseguibile autonomo con queste icone incorporate.

Ma cosa succede se abbiamo così tanti file? Supponiamo di avere 1000 icone da utilizzare nel nostro programma. È molto inadeguato scrivere a mano il file spec. Ci deve essere un sistema di loop per leggere la directory dei file e aggiungere questi file in modo dinamico. Ma non sono riuscito a trovare come aggiungere questi file in modo dinamico. Non c'è alcuna possibilità di aggiungere questi tanti file a mano, penso. Se qualcuno lo sa, per favore condividi.

+0

Prova 'cx_freeze'. Ho provato 'py2exe',' pyinstaller', qualche altro programma casuale, e solo 'cx_freeze' ha funzionato per me (ho usato PyQt4). Se vuoi vedere il mio codice per fare un binario, è su GitHub: https://github.com/Blender3D/Bindery/blob/master/tools/binary.py – Blender

+0

Grazie per il tuo interesse. Ma cx_freeze crea solo file .exe. Voglio costruire il programma di tutte le piattaforme. Quindi devo usare pyinstaller. Ma ho dei grossi problemi. – user1150508

+0

No, 'cx_freeze' crea binari anche per Linux. Mac richiede Py2app. – Blender

risposta

5

Nel creare il mio eseguibile, mi sono imbattuto anche in questo problema. Poiché il file .spec utilizza python, il modulo glob era la mia soluzione.

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 

Linea 2 per quanto riguarda icon.ico era separata perché aveva un'estensione di file diversa, e può quindi essere escluso. '.. \ pathfinder' è il percorso per tutti i file del mio programma (relativo dalla directory pyinstaller). glob cerca nella directory tutti i file .png (ne ho 65 e ho rifiutato di scriverli tutti a mano) e restituisce un elenco di essi come stringhe, intere directory relative intatte. Per separarlo in un elenco di nomi di file, ho usato string.split() sul backslash. Quindi, per ognuno, aggiungi ad una lista creata dall'utente una tupla della parte finale della divisione della stringa (che finirà per essere solo il nome file dell'immagine) e il percorso completo. Infine, con un elenco di tutti i file, aggiungilo a a.datas.

Ho confermato tramite la riga di comando che funziona effettivamente, ed è possibile ricopiare il ciclo per eventuali estensioni di file aggiuntive.

Sfortunatamente, anche se sembra tirare e collegare correttamente i nomi dei file, il mio eseguibile non sembra ancora essere creato con i file (o l'eseguibile non riesce a trovare i file all'interno dei propri dati) e devo ancora avere il immagini raw nella stessa directory per farlo funzionare; forse ho gli elementi della tupla ordinati in modo errato (e quindi, se è così, dovresti adattare il mio codice di conseguenza). Speriamo che questo carico dinamico funzioni comunque per te. imageParts [-1] rappresenta ciascun nomefile di .png e eachImage rappresenta il suo percorso completo (o percorso relativo se è ciò che è stato usato in glob).

1

Se tutte le immagini sono elencati sotto stessa directory è possibile utilizzare albero

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