python deployment pyqt cx-freeze

python - cx_Freeze-Previniendo incluyendo paquetes innecesarios



deployment pyqt (1)

La razón por la que no funciona el comando "excluye" fue que olvidé incluir las opciones de compilación en la configuración. Después de agregar la línea respectiva en el código excluyendo trabajos:

from cx_Freeze import setup, Executable import sys # exclude unneeded packages. More could be added. Has to be changed for # other programs. build_exe_options = {"excludes": ["tkinter", "PyQt4.QtSql", "sqlite3", "scipy.lib.lapack.flapack", "PyQt4.QtNetwork", "PyQt4.QtScript", "numpy.core._dotblas", "PyQt5"], "optimize": 2} # Information about the program and build command. Has to be adjusted for # other programs setup( name="MyProgram", # Name of the program version="0.1", # Version number description="MyDescription", # Description options = {"build_exe": build_exe_options}, # <-- the missing line executables=[Executable("MyProgram.py", # Executable python file base = ("Win32GUI" if sys.platform == "win32" else None))], )

Esto disminuyó el tamaño del programa de 230MB a 120MB. Sin embargo, no encontré una buena manera de excluir todos los paquetes innecesarios. Por prueba y error (eliminando los archivos más grandes en la carpeta de compilación en cuanto a las pruebas), descubrí las clases que puedo excluir.

Intenté si los backends matplotlib causan el problema y finalmente descubrí que este no es el caso. No obstante, si alguien necesita un código para excluir todos los módulos de un determinado esquema de nombre en una carpeta particular, excepto algunos especiales, puede ajustar lo siguiente a sus necesidades:

mplBackendsPath = os.path.join(os.path.split(sys.executable)[0], "Lib/site-packages/matplotlib/backends/backend_*") fileList = glob.glob(mplBackendsPath) moduleList = [] for mod in fileList: modules = os.path.splitext(os.path.basename(mod))[0] if not module == "backend_qt4agg": moduleList.append("matplotlib.backends." + modules) build_exe_options = {"excludes": ["tkinter"] + moduleList, "optimize": 2}

Me alegraría con soluciones más elegantes. Las ideas adicionales son bienvenidas. Sin embargo, considero el problema como resuelto para mí.

He codificado un pequeño programa python usando PyQt4. Ahora, quiero usar cx_Freeze para crear una aplicación independiente. Todo funciona bien: cx_Freeze incluye automáticamente todos los módulos necesarios; el exe resultante funciona.

El único problema es que cx_Freeze incluye muchos módulos innecesarios en la versión independiente. Aunque solo uso QtCore y QtGui, también se incluyen módulos como sqlite3, QtNetwork o QtScript. Sorprendentemente, también encontré las dlls PyQt5 en la carpeta resultante. Me parece que cx_Freeze usa todos los paquetes PyQt que he instalado. El resultado es un programa de 200Mb, aunque solo escribí un pequeño script.

¿Cómo puedo prevenir este comportamiento?

Yo uso el siguiente setup.py:

import sys from cx_Freeze import setup, Executable setup( name="MyProgram", version="0.1", description="MyDescription", executables=[Executable("MyProgram.py", base = "Win32GUI")], )

Traté de excluir explícitamente algunos paquetes (aunque es bastante complicado excluir todos los módulos Qt no utilizados) agregando este código:

build_exe_options = {"excludes": ["tkinter", "PyQt4.sqlite3", "PyQt4.QtOpenGL4", "PyQt4.QtSql"]}

pero los módulos superiores todavía se usaban. También intenté

build_exe_options = {"excludes": ["tkinter", "PyQt4.sqlite3", "QtOpenGL4", "QtSql"]}

con el mismo resultado

Además de los paquetes QT de nedless, también encuentro carpetas innecesarias con nombres como "imageformats", "tcl" y "tk". ¿Cómo puedo incluir solo los archivos necesarios para mantener la carpeta independiente y el instalador lo más pequeños posible?

Busqué en Google este problema por horas, pero solo encontré este hilo que no me ayudó.

Estoy ejecutando python 3.4.2 amd64 en Windows 8.

Estoy contento con cada solución que me da el resultado deseado "independiente" con un tamaño razonable. Intenté también pyqtdeploy pero encontré el error: módulo (s) desconocido (s) en QT (pero esta es una pregunta diferente).

Editar:

Estoy usando dos módulos. Una es la clase de GUI creada por uic, "MyProgramGUIPreset". En este archivo, existen los siguientes comandos de importación:

from PyQt4 import QtCore, QtGui from matplotlibwidget import MatplotlibWidget

En el módulo principal hago las siguientes importaciones:

import MyProgramGUIPreset import numpy as np from PyQt4.QtGui import QApplication, QMainWindow, QMessageBox import sys from math import *

Tal vez esto ayude a descubrir dónde está el problema.