2011-02-04 3 views
7

Sto cercando di utilizzare py2exe-0.6.9.win32 per concludere un'applicazione che ho scritto in Python2.6.5 utilizzando i seguenti librerie di oggetti con i nomi dei file scaricare associati:py2exe e non NumPy andare d'accordo

matplotlib -0.99.3.win32

numpy-1.4.1-win32

SciPy-0.8.0b1-win32

wxPython2.8-win32-unicode-2.8.11.0

Ricevo messaggi di errore quando tento di avviare il file .exe risultante. Al momento, il messaggio di errore è correlato a numpy, anche se prima stavo ottenendo qualcosa relativo ai file di dati di matplot lib non caricati e bloccando così il lancio del mio file exe.

Piuttosto che postare un miglio di codice e tutti i messaggi di errore, sto postando una domanda più generale: Qualcuno può mostrarmi alcune istruzioni per fare in modo che tutte queste librerie di oggetti e versioni funzionino bene insieme con py2exe per creare un lavoro file exe?

Ho letto cose che hanno trovato ricerche su google sull'argomento, ma sembra una caccia all'oca selvaggia in quanto tutti usano versioni diverse di cose diverse. Posso modificare alcune versioni di alcune di queste librerie di oggetti se questo fa la differenza, ma ho già scritto 5.000 linee di codice in questa applicazione di elaborazione del segnale, e preferirei non dover riscriverle tutte, se possibile.


EDIT:

Ecco una versione semplificata del mio codice in un file chiamato GUIdiagnostics.py che ho fatto per testare la capacità del mio script py2exe di importare tutte le librerie che ho bisogno di la mia vera applicazione:

import time 
import wxversion 
import wx 
import csv 
import os 
import pylab as p 
from scipy import stats 
import math 
from matplotlib import * 
from numpy import * 
from pylab import * 
import scipy.signal as signal 
import scipy.optimize 
import Tkinter 

ID_EXIT = 130 

class MainWindow(wx.Frame): 
    def __init__(self, parent,id,title): 
     wx.Frame.__init__(self,parent,wx.ID_ANY,title, size = (500,500), style =  wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE) 

     # A button 
     self.button =wx.Button(self, label="Click Here", pos=(160, 120)) 
     self.Bind(wx.EVT_BUTTON,self.OnClick,self.button) 

     # the combobox Control 
     self.sampleList = ['first','second','third'] 
     self.lblhear = wx.StaticText(self, label="Choose TestID to filter:", pos=(20, 75)) 
     self.edithear = wx.ComboBox(self, pos=(160, 75), size=(95, -1),  choices=self.sampleList, style=wx.CB_DROPDOWN) 

     # the progress bar 
     self.progressMax = 3 
     self.count = 0 
     self.newStep='step '+str(self.count) 
     self.dialog = None 

     #-------Setting up the menu. 
     # create a new instance of the wx.Menu() object 
     filemenu = wx.Menu() 

     # enables user to exit the program gracefully 
     filemenu.Append(ID_EXIT, "E&xit", "Terminate the program") 

     #------- Creating the menu. 
     # create a new instance of the wx.MenuBar() object 
     menubar = wx.MenuBar() 
     # add our filemenu as the first thing on this menu bar 
     menubar.Append(filemenu,"&File") 
     # set the menubar we just created as the MenuBar for this frame 
     self.SetMenuBar(menubar) 
     #----- Setting menu event handler 
     wx.EVT_MENU(self,ID_EXIT,self.OnExit) 

     self.Show(True) 

    def OnExit(self,event): 
     self.Close(True) 

    def OnClick(self,event): 
     try: 
      if not self.dialog: 
       self.dialog = wx.ProgressDialog("Progress in processing your data.", self.newStep, 
              self.progressMax, 
              style=wx.PD_CAN_ABORT 
              | wx.PD_APP_MODAL 
              | wx.PD_SMOOTH) 
      self.count += 1 
      self.newStep='Start' 
      (keepGoing, skip) = self.dialog.Update(self.count,self.newStep) 
      TestID = self.edithear.GetValue() 

      self.count += 1 
      self.newStep='Continue.' 
      (keepGoing, skip) = self.dialog.Update(self.count,self.newStep) 
      myObject=myClass(TestID) 
      print myObject.description 

      self.count += 1 
      self.newStep='Finished.' 
      (keepGoing, skip) = self.dialog.Update(self.count,self.newStep) 

      self.count = 0 

      self.dialog.Destroy() 

     except: 
      self.dialog.Destroy() 
      import sys, traceback 
      xc = traceback.format_exception(*sys.exc_info()) 
      d = wx.MessageDialog(self, ''.join(xc),"Error",wx.OK) 
      d.ShowModal() # Show it 
      d.Destroy() #finally destroy it when finished 

class myClass(): 
    def __init__(self,TestID): 
     self.description = 'The variable name is: '+str(TestID)+'. ' 

app = wx.PySimpleApp() 
frame = MainWindow(None,-1,"My GUI") 
app.MainLoop() 

Ecco il codice per setup.py, che è il file che contiene il mio codice py2exe:

from distutils.core import setup 
import py2exe 

# Remove the build folder, a bit slower but ensures that build contains the latest 
import shutil 
shutil.rmtree("build", ignore_errors=True) 

# my setup.py is based on one generated with gui2exe, so data_files is done a bit differently 
data_files = [] 
includes = [] 
excludes = ['_gtkagg', '_tkagg', 'bsddb', 'curses', 'pywin.debugger', 
     'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl', 
     'Tkconstants', 'Tkinter', 'pydoc', 'doctest', 'test', 'sqlite3' 
     ] 
packages = ['pytz'] 
dll_excludes = ['libgdk-win32-2.0-0.dll', 'libgobject-2.0-0.dll', 'tcl84.dll', 
      'tk84.dll'] 
icon_resources = [] 
bitmap_resources = [] 
other_resources = [] 

# add the mpl mpl-data folder and rc file 
import matplotlib as mpl 
data_files += mpl.get_py2exe_datafiles() 

setup(
    windows=['GUIdiagnostics.py'], 
         # compressed and optimize reduce the size 
    options = {"py2exe": {"compressed": 2, 
         "optimize": 2, 
         "includes": includes, 
         "excludes": excludes, 
         "packages": packages, 
         "dll_excludes": dll_excludes, 
         # using 2 to reduce number of files in dist folder 
         # using 1 is not recommended as it often does not work 
         "bundle_files": 2, 
         "dist_dir": 'dist', 
         "xref": False, 
         "skip_archive": False, 
         "ascii": False, 
         "custom_boot_script": '', 
        } 
      }, 

    # using zipfile to reduce number of files in dist 
    zipfile = r'lib\library.zip', 

    data_files=data_files 
) 

ho eseguito questo codice digitando la seguente riga nel l'interfaccia a riga di comando di Windows (cmd.exe) secondo il seguente link:

setup.py py2exe 

py2exe poi corre, ma quando provo a lanciare la risultante file .exe, viene creato un file di log che contiene il seguente messaggio:

Traceback (most recent call last): 
    File "setup.py", line 6, in <module> 
    File "zipextimporter.pyo", line 82, in load_module 
    File "pylab.pyo", line 1, in <module> 
    File "zipextimporter.pyo", line 82, in load_module 
    File "matplotlib\pylab.pyo", line 206, in <module> 
    File "zipextimporter.pyo", line 82, in load_module 
    File "matplotlib\mpl.pyo", line 3, in <module> 
    File "zipextimporter.pyo", line 82, in load_module 
    File "matplotlib\axes.pyo", line 14, in <module> 
    File "zipextimporter.pyo", line 82, in load_module 
    File "matplotlib\collections.pyo", line 21, in <module> 
    File "zipextimporter.pyo", line 82, in load_module 
    File "matplotlib\backend_bases.pyo", line 32, in <module> 
    File "zipextimporter.pyo", line 82, in load_module 
    File "matplotlib\widgets.pyo", line 12, in <module> 
    File "zipextimporter.pyo", line 82, in load_module 
    File "matplotlib\mlab.pyo", line 388, in <module> 
TypeError: unsupported operand type(s) for %: 'NoneType' and 'dict' 

qualcuno mi può mostrare come modificare setup.py in modo che py2exe può creare un eseguibile utilizzabile in esecuzione NumPy, SciPy, matplotlib, ecc?


SECONDO EDIT:

OK. Ho provato di nuovo il consiglio di RC oggi, ora che ho una mente nuova per questo, e ho avuto lo stesso errore, ma lo includo di seguito. Ecco il codice per un file chiamato cxsetup.py che ho creato seguendo il modello: http://cx-freeze.sourceforge.net/cx_Freeze.html.

from cx_Freeze import setup, Executable 

setup(
     name = "Potark", 
     version = "0.1", 
     description = "My application.", 
     executables = [Executable("Potark-ICG.py")]) 

Purtroppo, eseguirlo nella riga di comando (cmd.exe) con il comando:

python cxsetup.py build 

genera il seguente errore nella riga di comando:

ImportError: No module named cx_Freeze 

La directory in la riga di comando è la directory per la mia applicazione, che si trova in una sottocartella del desktop. Questo è diverso dalla directory per l'applicazione python, ma presumo che cmd.exe possa capirlo perché python può capirlo. Mi sbaglio? Come prova, ho aggiunto la seguente riga di codice alla prima linea di cxsetup.py:

import matplotlib 

Ma che ha generato l'errore pressoché identica:

ImportError: No module named matplotlib 

Ho cercato di mantenere questa discussione concentrato e breve, ma sta diventando un po 'lungo. Qualcuno può aiutarmi con questo? Mi dispiacerebbe fare tutto il lavoro di passare a cx_freeze solo per scoprire che non può funzionare con NumPy, matplotlib, SciPy, ecc

+0

forse si potrebbe provare con cxfreeze e vedere se aiuta a creare un exe di lavoro –

+0

(cancellato scusa) –

+0

Grazie. L'ho provato, ma ricevo un messaggio di errore diverso da cxfreeze e preferirei mantenere questo thread focalizzato in modo da non confondere le persone con troppi codici o troppi messaggi di errore. Questo aspetto della programmazione è nuovo per me. – MedicalMath

risposta

0

Come altri hanno già detto, py2exe sembra richiedere brutte e casuali correzioni caso per caso ... sembra che non ci sia alcun modo per aggirarlo. Inoltre, alcuni errori si rifiutano di andare via e non influiscono sul programma, ma fanno sì che il programma informi l'utente che è stato creato un log degli errori dopo l'uscita. Per evitare che, io uso questo codice:

import sys 
IS_USING_PY2EXE = hasattr(sys, "frozen") 

# Redirect output to a file if this program is compiled.  
if IS_USING_PY2EXE: 
    # Redirect log to a file. 
    LOG_FILENAME = os.path.join(logDir, "myfile.log") 
    print('Redirecting Stderr... to %s' % LOG_FILENAME) 
    logFile = open(os.path.join(LOG_FILENAME),"w") # a --> append, "w" --> write 

    sys.stderr = logFile 
    sys.stdout = logFile 
0

questo potrebbe me che sono stupido, ma perchè non si tenta di aggiornare il tuo SciPy da 0.8.0b1 per 0.8.0 e fare lo stesso con matplotlib? Numpy 1.4.1 dovrebbe ancora andare bene.