[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