【问题标题】:Build images and some configuration files like txt and xml files with pyinstaller使用 pyinstaller 构建图像和一些配置文件,例如 txt 和 xml 文件
【发布时间】:2012-01-15 15:34:19
【问题描述】:

在将图像和 txt 等数据文件添加到 python 程序时,我遇到了 pyinstaller 的问题。例如,我创建了一个带有图标的工具栏,并将它们存储在一个名为 images 的单独文件夹中。我还有一些 txt 和 xml 文件来存储一些配置。这些 txt ant xml 文件存储在另一个名为 data_files 的文件夹中。所有的 py 文件都存储在另一个名为 source 的文件夹中。

当我尝试使用 pyinstaller 构建这个 python 程序时,pyinstaller 可以成功构建所有源文件夹,但无法构建 images 和 data_files 文件夹。我检查了 pyinstaller 的文档,但找不到任何解决方案。我进行了很多谷歌搜索,发现只有 this 资源有帮助,但这是一个非常不足的资源。

我的主要问题是:如何使用 pyinstaller 构建带有单独构建的文件夹(例如 images 和 confs)的 exe 文件?

编辑: 我找到了解决方案。创建规范文件时,您必须添加 a.datas 参数。

# -*- mode: python -*-
a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), '/home/vmode/Desktop/derlem2/sources/TextSTAT.py'],
             pathex=['/home/pyinstaller'])
a.datas += [("Images/New.gif","/home/vmode/Desktop/derlem2/Images/New.gif","DATA")]
a.datas += [("Images/Open.gif","/home/vmode/Desktop/derlem2/Images/Open.gif","DATA")]
a.datas += [("Images/Column.gif","/home/vmode/Desktop/derlem2/Images/Column.gif","DATA")]
pyz = PYZ(a.pure)
exe = EXE( pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name=os.path.join('dist', 'TextSTAT'),
          debug=False,
          strip=False,
          upx=True,
          console=1 )

上面的规范代码是为我的项目设计的。正如在这个规范代码中看到的,我已经包含了 3 个使用 python 程序构建的图标。生成程序时,会有一个独立的可执行文件,其中嵌入了这些图标。

但是如果我们有这么多文件怎么办?假设我们的程序中有 1000 个图标要使用。手动写到规范文件是非常不合适的。必须有一个循环系统来读取文件目录并动态添加这些文件。但我找不到如何动态添加这些文件。我认为没有任何机会手动添加这么多文件。如果有人知道,请分享。

【问题讨论】:

  • 试试cx_freeze。我尝试了py2exepyinstaller、其他一些随机程序,但只有cx_freeze 为我工作(我使用了PyQt4)。如果你想看我制作二进制的代码,它在 GitHub 上:github.com/Blender3D/Bindery/blob/master/tools/binary.py
  • 感谢您的关注。但是 cx_freeze 只构建 .exe 文件。我想为所有平台构建程序。所以我必须使用pyinstaller。但是有一些大问题。
  • 不,cx_freeze 也为 Linux 创建二进制文件。 Mac 需要 Py2app。
  • 另外,您介意为其他人发布您的解决方案吗?

标签: python pyinstaller


【解决方案1】:

在创建我的可执行文件时,我也遇到了这个问题。因为 .spec 文件使用的是 python,所以 glob 模块是我的解决方案。

imagesList = []
imagesList.append( ('icon.ico', '..\\pathfinder\\icon.ico',  'DATA') )
import glob
allImages = glob.glob('..\\pathfinder\\*.png')
for eachImage in allImages:
    imageParts = eachImage.split('\\')
    imagesList.append( (imageParts[-1], eachImage,  'DATA') )
print imagesList
a.datas += imagesList

关于 icon.ico 的第 2 行是单独的,因为它具有不同的文件扩展名,因此可以排除。 '..\pathfinder' 是我所有程序文件的路径(相对于 pyinstaller 目录)。 glob 在目录中搜索所有 .png 文件(我有 65 个并且拒绝手动编写它们)并将它们的列表作为字符串返回,完整的相对目录完好无损。为了将它分成文件名列表,我在反斜杠上使用了 string.split()。然后对于每个,将字符串拆分的最后部分(最终只是图像的文件名)和完整路径名的元组附加到用户制作的列表中。最后,将所有文件的列表添加到 a.datas 中。

我已通过命令行确认这确实可以正常工作,您可以重新复制循环以获得任何其他文件扩展名。

不幸的是,即使它似乎正确地提取和附加了文件名,我的可执行文件似乎仍然没有用这些文件创建(或者可执行文件在它自己的数据中找不到文件),我仍然必须拥有原始文件同一目录中的图像以使其正常工作;也许我的元组元素排序不正确(因此,如果是这样,您应该相应地调整我的代码)。不过,希望这种动态负载仍然对您有用。 imageParts[-1] 代表每个 .png 的文件名, eachImage 代表其完整路径(或相对路径,如果这是 glob 中使用的)。

【讨论】:

    【解决方案2】:

    如果所有图像都列在同一目录下,则可以使用 Tree

    dict_tree = Tree('/home/vmode/Desktop/derlem2/Images', prefix = 'Images')
    a.datas += dict_tree
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-28
      • 2016-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多