How to compile all resources into one executable f

2019-01-25 19:04发布

问题:

I've wrote GTK application with python.

All graphical user interface is in glade file, and there are some images used. I wish to compile my application into EXEcutable file. For that I'm using PyInstaller compiler and UPX packer.

I've done as manual says:

python Configure.py
python Makespec.py --onefile --windowed --upx /path/to/yourscript.py
python Build.py /path/to/yourscript.spec

PyInstaller works perfectly and create one exe file. But to make my application work correctly i have to copy my glade and image files into exe's folder.

Is there any way to compile those files into executable?

I've edited my spec file in various ways but i can not achieve what i want. Spec file below only copies file to directory, but does not compile into executable file

# -*- mode: python -*-
a = Analysis([os.path.join(HOMEPATH,'support\\_mountzlib.py'), os.path.join(HOMEPATH,'support\\useUnicode.py'), 'r:\\connection\\main.py'],
             pathex=['C:\\Documents and Settings\\Lixas\\Desktop\\pyinstaller-1.5-rc1'])

pyz = PYZ(a.pure)

exe = EXE( pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name=os.path.join('dist', 'NetworkChecker.exe'),
          debug=False,
          strip=False,
          upx=True,
          console=False,
          icon='r:\\connection\\ikona.ico'        )

coll = COLLECT(
    exe,
    [('gui.glade', 'r:\\connection\\gui.glade', 'DATA')],
    [('question16.png', 'r:\\connection\\question16.png', 'DATA')],
#   a.binaries,
#   strip=False,
    upx=True,
    name='distFinal')

I wish to have only one executable file with everything included into

回答1:

PyInstaller does allow you to bundle all your resources into the exe, without the trickyness of turning your data files into .py files -- your COLLECT object seems to be correct, the tricky step is accessing these files at runtime. PyInstaller will unpack them into a temporary directory and tell you where they are with the _MEIPASS2 variable. To get the file paths in both development and packed mode, I use this:

def resource_path(relative):
    return os.path.join(
        os.environ.get(
            "_MEIPASS2",
            os.path.abspath(".")
        ),
        relative
    )


# in development
>>> resource_path("gui.glade")
"/home/shish/src/my_app/gui.glade"

# in deployment
>>> resource_path("gui.glade")
"/tmp/_MEI34121/gui.glade"


回答2:

With a few changes, you can incorporate everything into your source code and thus into your executable file.

If you run gdk-pixbuf-csource on your image files, you can convert them into strings, which you can then load using gtk.gdk.pixbuf_new_from_inline().

You can also include your Glade file as a string in the program and then load it using gtk.Builder.add_from_string().



回答3:

Is there any way to compile those files into executable?

Strictly speaking: no, because you compile source code, while the glade file is XML and the images are binary data. What you would normally do is to create an installer (i.e. a self-unpacking archive that will place different files in the correct directories when the installer is ran).

EDIT: If your concern is simply to have a one-file executable (so it's not about "compiling" but really about the number of files that are permanently written on the filesystem) you could try to use this script based on py2exe. What it does, is to create temporary files each time the program is ran, removing them when execution is completed.

EDIT2: Apparently what you are asking for is also possible under PyInstaller. From the documentation:

By default, pyinstaller.py creates a distribution directory containing the main executable and the dynamic libraries. The option --onefile specifies that you want PyInstaller to build a single file with everything inside.