Bundling data files with PyInstaller (--onefile)

前端 未结 13 1591
清歌不尽
清歌不尽 2020-11-21 13:28

I\'m trying to build a one-file EXE with PyInstaller which is to include an image and an icon. I cannot for the life of me get it to work with --onefile.

<
13条回答
  •  不思量自难忘°
    2020-11-21 13:48

    I have been dealing with this issue for a long(well, very long) time. I've searched almost every source but things were not getting in a pattern in my head.

    Finally, I think I have figured out exact steps to follow, I wanted to share.

    Note that, my answer uses informations on the answers of others on this question.

    How to create a standalone executable of a python project.

    Assume, we have a project_folder and the file tree is as follows:

    project_folder/
        main.py
        xxx.py # modules
        xxx.py # modules
        sound/ # directory containing the sound files
        img/ # directory containing the image files
        venv/ # if using a venv
    

    First of all, let's say you have defined your paths to sound/ and img/ folders into variables sound_dir and img_dir as follows:

    img_dir = os.path.join(os.path.dirname(__file__), "img")
    sound_dir = os.path.join(os.path.dirname(__file__), "sound")
    

    You have to change them, as follows:

    img_dir = resource_path("img")
    sound_dir = resource_path("sound")
    

    Where, resource_path() is defined in the top of your script as:

    def resource_path(relative_path):
        """ Get absolute path to resource, works for dev and for PyInstaller """
        base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
        return os.path.join(base_path, relative_path)
    

    Activate virtual env if using a venv,

    Install pyinstaller if you didn't yet, by: pip3 install pyinstaller.

    Run: pyi-makespec --onefile main.py to create the spec file for the compile and build process.

    This will change file hierarchy to:

    project_folder/
        main.py
        xxx.py # modules
        xxx.py # modules
        sound/ # directory containing the sound files
        img/ # directory containing the image files
        venv/ # if using a venv
        main.spec
    

    Open(with an edior) main.spec:

    At top of it, insert:

    added_files = [
    
    ("sound", "sound"),
    ("img", "img")
    
    ]
    

    Then, change the line of datas=[], to datas=added_files,

    For the details of the operations done on main.spec see here.

    Run pyinstaller --onefile main.spec

    And that is all, you can run main in project_folder/dist from anywhere, without having anything else in its folder. You can distribute only that main file. It is now, a true standalone.

提交回复
热议问题