python 3.x - make - Construyendo ejecutables para Python 3 y PyQt
python executable (2)
Construí una aplicación bastante simple en Python 3.1 usando PyQt4. Una vez hecho esto, quiero que la aplicación se distribuya a las computadoras sin ninguna de las instaladas.
Casi exclusivamente me preocupo por las plataformas Windows, por lo que mi objetivo es tener un solo archivo ejecutable y tal vez algunos archivos de recursos y .dlls al final.
Habiendo buscado alrededor, llegué a la conclusión de que
- py2exe solo soporta Python hasta la versión 2.7
- Pyinstaller solo admite Python hasta la versión 2.6
- cx_Freeze no funciona para mí porque sigo recibiendo el siguiente error cuando intento ejecutar mi binario de compilación exitosa:
Y:/Users/lulz/build/exe.win32-3.1>system_shutdown.exe
Traceback (most recent call last):
File "Y:/Program Files (x86)/Python/lib/site-packages/cx_Freeze/initscripts/Console3.py", line 27, in exec(code, m.__dict__)
File "Y:/Users/lulz/Documents/Coding/Python3/projects/System Shutdown/system_shutdown.pyw", line 5, in from PyQt4 import QtCore
File "ExtensionLoader_PyQt4_QtCore.py", line 16, in AttributeError: ''NoneType'' object has no attribute ''modules''
Así que mi problema es básicamente dos problemas aquí:
- ¿Hay otra forma, pero cx_Freeze para construir binarios con mi configuración?
- Si no, ¿cuál podría ser el problema de cx_Freeze?
Puedo proporcionar más información sobre el segundo problema si es necesario, como mi llamada de cx_Freeze, mi script de configuración de distutils, etc.
Gracias ya por su ayuda y comentarios.
Para Python 3.3 y versiones posteriores, hay una buena resolución aquí: py2exe: generar un solo archivo ejecutable
Instala py2exe:
pip install py2exe
Luego agregue, además del archivo ''your_script.py'', el siguiente archivo ''Make_exe.py'':
from distutils.core import setup
import py2exe, sys
class Make_exe():
def __init__(self, python_script):
sys.argv.append(''py2exe'')
setup(
console=[{''script'': python_script}],
zipfile = None,
options={
''py2exe'':
{
''bundle_files'': 1,
''compressed'': True,
# Add includes if necessary, e.g.
''includes'': [''lxml.etree'', ''lxml._elementpath'', ''gzip''],
}
}
)
if __name__ == ''__main__'':
Make_exe(''your_script.py'')
Y si desea que ''your_script.py'' se reconstruya a sí mismo como ''your_script.exe'' cada vez que lo ejecute en Python , puede agregar a su principal:
import subprocess
import sys
if __name__ == ''__main__'':
currentFile = sys.argv[0]
if currentFile.lower().endswith(".py"):
exitCode = subprocess.call("python Make_exe.py")
if exitCode==0 :
dirName = os.path.dirname(currentFile)
exeName = os.path.splitext(os.path.basename(currentFile))[0] + ''.exe''
exePath = dirName + "/dist/" + exeName
cmd = [exePath] + sys.argv[1:]
print ("Executing command:/n %s" % cmd)
exitCode = subprocess.call(cmd)
sys.exit(exitCode)
else:
print ("This will be executed only within the new generated EXE File...")
Puede solucionar esto agregando una línea de código a freeze.py en su paquete cx_Freeze.
Se describe aquí: http://www.mail-archive.com/[email protected]/msg00212.html
Funcionó para mí al menos :)
Saludos, Almar