[DEPRECATED if you use ETS 4.0 — see the new version]
So, guys, today is a great day, BIG news : I succeeded packaging an Enthought Traits UI script inside a standalone package.
Keys to remember:
- To get things to work, I had to manually import all packages used, surely the Wx backend.
- It’s not possible, currently, to bundle and to compress.
- I add the /images folders manually using the data_files variable.
My configuration:
- Windows XP Pro 32bits
- Python 2.5.4
- Numpy 1.5.0
- Py2exe 0.6.9
- Distutils 2.5.1
- Enthought Tool Suite ETS 3.5.0 from SVN
So, here is a typical example :
from enthought.traits.api import * class Person(HasTraits): name = Str age = CInt weight = CFloat if __name__ == "__main__": joe = Person() joe.configure_traits() print joe.name, joe.age, joe.weight
You’ll see below, the ETS from SVN in downloaded in “c:\python_install\ETS”
The setup.py script looks like :
from distutils.core import setup import py2exe import os import enthought includes = [] includes.append('numpy') includes.append('scipy') includes.append('numpy.core') includes.append('wx') includes.append('wx.*') includes.append('enthought') includes.append('enthought.kiva') includes.append('enthought.traits') includes.append('enthought.traits.ui') includes.append('enthought.traits.ui.wx') includes.append('enthought.traits.ui.wx.*') includes.append('enthought.pyface.*') includes.append('enthought.pyface.ui.*') includes.append('enthought.pyface.ui.wx.*') includes.append('enthought.pyface.ui.wx.action.*') includes.append('enthought.pyface.ui.wx.timer.*') includes.append('enthought.pyface.ui.wx.wizard.*') includes.append('enthought.pyface.ui.wx.workbench.*') includes.append('enthought.enable') includes.append('enthought.enable.*') includes.append('enthought.enable.drawing') includes.append('enthought.enable.image') includes.append('enthought.enable.image_title') includes.append('enthought.enable.traits') includes.append('enthought.enable.wx_backend') packages = [] ETS_folder = r'C:\python_install\ETS' data_folders = [] data_folders.append( ( os.path.join(ETS_folder,r'TraitsGUI\enthought\pyface\images') , 'enthought/pyface/images') ) data_folders.append( ( os.path.join(ETS_folder,r'Enable\enthought\enable\images') , 'enthought/enable/images') ) data_folders.append( ( os.path.join(ETS_folder,r'TraitsBackendWX\enthought\pyface\ui\wx\images') , 'enthought/pyface/ui/wx/images') ) data_folders.append( ( os.path.join(ETS_folder,r'TraitsBackendWX\enthought\traits\ui\wx\images') , 'enthought/traits/ui/wx/images') ) data_folders.append( ( os.path.join(ETS_folder,r'TraitsGUI\enthought\traits\ui\image\library') , 'enthought/traits/ui/image/library') ) data_files = [] for folder, relative_path in data_folders: for file in os.listdir(folder): f1 = os.path.join(folder,file) if os.path.isfile(f1): # skip directories f2 = relative_path, [f1] data_files.append(f2) setup(console=['helloworld.py'], options = {"py2exe": { "optimize": 0, "packages": packages, "includes": includes, "dist_dir": 'dist', "bundle_files":2, "xref": False, "skip_archive": True, "ascii": False, "custom_boot_script": '', "compressed":False, },}, data_files=data_files)
then, to launch the packing, just do:
$ python setup.py py2exe
The build and packing process takes some time, but it works. The /dist directory contains a lot of libraries (~100 MB), there must be a way to cut down the imports, but I have to admit, now that I have a successful build, I really don’t care if it’s 110 MB or 80 MB !
to launch the script, just hit “helloworld.exe” in the /dist folder. Note, I set the “console” value to “helloworld.py”, because I wanted to have a python console running behind my GUI. If you replace “console” by “windows”, double-clicking “helloworld.exe” will just load your GUI.
Nota Bene : if you need matplotlib, here is the way:
Replace:
data_files = []
Load the related files instead:
import matplotlib as mpl data_files = mpl.get_py2exe_datafiles()
Cheers & Have Fun !
Thomas
Hi Thomas
Did you ever find a way around the archive problem, and the way includes are handled. I am stuck trying to created a bundled exe file with py2exe and traits ui.
Thanks,
Morten
Morten,
No, actually not. I’ve bundled the whole /dist folder in a single setup.exe using NSI. For the end user, it unpacks the data in %programfiles%/MyProgram/ and creates a link in the start menu. For most users, that’s simple enough and they don’t go checking the complexity of the /MyProgram folder !
I’m pretty sure that it will never be easy to properly include all the enthought packages, simply because they do a lot of very clever relative imports, etc.
Cheers,
Thom