Pyinstaller:生成-exe文件+文件夹(在--onefile模式下)

问题描述 投票:0回答:4

现在我正在使用 Pyinstaller。 我有一个从 img 文件夹获取图像的脚本..

/python
|----/img
|----|----icon1.ico
|----|----icon2.ico
|----maint.py

我生成.exe的脚本是

pyinstaller.py --windowed --noconsole --clean --onefile maint.py

问题是只生成了.exe文件,而忽略了整个文件夹/img。

问题:我需要在上一行添加哪些额外语法才能自动获取 .exe 文件 + /img 文件夹?

我的意思是:执行 pyinstaller.py 脚本后,使用所有参数,我必须在 /dist 文件夹中看到:.exe 文件 + /img 文件夹,其中包含我的应用程序的所有图标或位图文件

谢谢

python user-interface exe pyinstaller packaging
4个回答
46
投票

这就是我解决问题的方法:

我正在使用当前版本的 PYInstaller + Python 2.67,并使用 Sublime Text 作为编辑器。

  1. 如果您的 Py 脚本需要一些文件、图标、图像,您必须包含一个从项目文件夹(开发中)或形成临时数据文件夹(如果部署)检索这些文件的函数。该脚本必须位于您的代码中放置相对路径以获取资源的部分。请严格遵守此指南

  2. 在前面的代码之后,您必须第一次执行 pyinstaller 命令 - 正如我在问题中发布的那样 - 。

  3. 现在,打开执行 PYInstaller(位于

    PYinstaller/YourAppName/
    )命令后生成的 .spec 文件,并在
    a.binaries
    行之后将下一行添加到
    EXE()
    函数中:

    exe = EXE(pyz,
              a.scripts,
              a.binaries,
              Tree('..\\python\\images', prefix='images\\'),
    ....
    

    请记住,在

    Tree(...)
    函数中,第一个参数是要放在外部的文件夹: 这意味着我想包含此文件夹的所有内容(请注意,我正在放置相对于 AppStart.txt 的相对路径)。 py 文件)进入我的 .EXE 文件的文件容器。

  4. 修改后重新执行 pyinstaller 命令,但在本例中指向我的

    .SPEC
    文件:

    pyinstaller.py --windowed --noconsole --clean --onefile AppStart\AppStart.spec
    

最后,我的应用程序可以作为可执行文件执行,而无需像有人提到的那样复制和粘贴所有外部文件夹。 但我一如既往地考虑实用的方法。

感谢您的支持。


2
投票

您还可以在另一个 python 脚本中运行 pyinstaller,然后使用

shutil.copytree()
将文件夹移到后面。或者对单个文件使用
shutil.copyfile()

import PyInstaller.__main__
import shutil

PyInstaller.__main__.run([
    'YourProgram.py',
    '--icon=UI/Your_Icon.ico',
    '--onefile',
    '--noconsole',
], )

shutil.copytree('path/', 'dist/path')

1
投票

您必须解决许多问题才能使其发挥作用。例如:

  • 获取正确的资源路径
  • 添加数据

第一个问题(如上所述)通过根据执行模式调整路径来解决。

def app_path(path):
    frozen = 'not'
    if getattr(sys, 'frozen', False):
            # we are running in executable mode
            frozen = 'ever so'
            app_dir = sys._MEIPASS
    else:
            # we are running in a normal Python environment
            app_dir = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(app_dir, path)

对于第二个问题,我使用通配符运算符(*)而不是树来添加我需要的内容。

added_files = [
         ( './pics/*', 'pics' ),
         ( './db/*', 'db' ),
         ]

然后在分析中,

datas = added_files

完整的答案相当长。我写了这篇文章,以一些微小的细节来展示我为解决问题所经历的事情。


0
投票

@上面的答案

这是不可能的,因为规范构建不支持 --onefile。

每个 Pyinstaller 错误消息:

option(s) not allowed: --onedir/--onefile --console/--nowindowed/--windowed/--noconsole makespec options not valid when a .spec file is given

除非旧版本支持。我尝试了 3.0 之前的每个版本,此时我停止了,因为我将被迫打破依赖项并继续依赖项追逐。

© www.soinside.com 2019 - 2024. All rights reserved.