有人用 Pyinstaller 成功地将数据文件捆绑到一个文件中吗?

Posted

技术标签:

【中文标题】有人用 Pyinstaller 成功地将数据文件捆绑到一个文件中吗?【英文标题】:Anyone successfully bundled data files into a single file with Pyinstaller? 【发布时间】:2016-12-21 10:05:48 【问题描述】:

我一直在梳理 Stack Overflow 和网络上的其他内容,了解如何将数据文件添加到我的 python 应用程序中:

import Tkinter

class simpleapp_tk(Tkinter.Tk):
    def __init__(self,parent):
        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.grid()

--- Everything Fine Here ---

        self.B = Tkinter.Button(self, text = 'Create Document', command = self.OnButtonClick)
        self.B.grid(column = 0, row = 6)


    def OnButtonClick(self):
        createDoc()

if __name__ == "__main__":
    app = simpleapp_tk(None)
    app.title('Receipt Form')
    app.iconbitmap(os.getcwd() + '/M.ico')
    app.mainloop()

我尝试使用 .spec 文件,但没有成功

Onedir 工作正常,但是当我尝试编译成单个可执行文件时,它会给出一个错误,即文件“M.ico”未定义。

如果有人能够使用 pyinstaller 将数据文件捆绑到一个文件中。请帮忙。谢谢。

我在运行 Python 2.7 和 PyInstaller 3.2 的 Windows 10 计算机上

【问题讨论】:

我认为你的问题是pyinstalleruses a temporary folder to extract the files。您已在您的代码中为冻结的应用程序指定为完成here。 @Repiklis 好的,我到底该如何使用它呢?我做app.iconbitmap(resource_path('/M.ico')) 与this 非常相似。您必须在规范文件的resources 中包含您的图标,并在代码中的答案底部添加两行(在设置图标之前)。如果您仍有问题,请告诉我。 @Repiklis 我完全按照你说的做了:我在规范的末尾添加了resources=['M.ico']),并在我的实际python文件中添加了if hasattr(sys, '_MEIPASS'): os.chdir(sys._MEIPASS),但我仍然收到错误:_tkinter.TclError: bitmap "C:\Users\micha\AppData\Local\Temp\_MEI69~1/M.ico" not defined M.ico 之前使用的斜线是错误的。在这种情况下应该是\\M.ico。更好的是,使用os.sep 来获取系统路径分隔符。 【参考方案1】:

您必须在 pyinstaller .spec 文件中或通过命令行选项指定要添加的每个数据文件(.spec 更容易。)下面是我的 .spec 文件,带有“datas”部分:

# -*- mode: python -*-

block_cipher = None


a = Analysis(['pubdata.py'],
             pathex=['.', '/interface','/recommender'],
             binaries=None,
             datas=[('WordNet/*.txt','WordNet'),
             ('WordNet/*.json','WordNet'),
             ('WordNet/pdf_parsing/*.json','pdf_parsing'),
             ('WordNet/pdf_parsing/*.xml','pdf_parsing'),
             ('images/*.png','images'),
             ('database/all_meta/Flybase/*.txt','all_meta'),
             ('database/all_meta/Uniprot/*.txt','all_meta'),
             ('database/json_files/*.json','json_files'),
             ('Data.db','.')],

             hiddenimports=['interface','recommender'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='GUI',
          debug=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='GUI')
app = BUNDLE(coll,
             name='App.app',
             icon=None)

在此之后,如果您尝试访问您在 .spec 文件中指定的任何数据文件,在您的代码中,您必须使用 Pyinstaller 的 _MEIPASS 文件夹来引用您的文件。以下是我对名为 Data.db 的文件的处理方式:

import sys
import os.path

        if hasattr(sys, "_MEIPASS"):
            datadir = os.path.join(sys._MEIPASS, 'Data.db')
        else:
            datadir = 'Data.db'

        conn = lite.connect(datadir)

上面的这个方法替换了这个单独的语句:

conn = lite.connect("Data.db")

当我经历同样的事情时,这个链接帮助了我很多: https://irwinkwan.com/2013/04/29/python-executables-pyinstaller-and-a-48-hour-game-design-compo/

希望这会有所帮助!

【讨论】:

以上是关于有人用 Pyinstaller 成功地将数据文件捆绑到一个文件中吗?的主要内容,如果未能解决你的问题,请参考以下文章

求帮助,配置PyInstaller不成功

用Pyinstaller把Python3.7程序打包成可执行文件exe

用Pyinstaller把Python3.7程序打包成可执行文件exe

用PyInstaller把Python代码打包成单个独立的exe可执行文件

pyinstaller使用大全

用 pyinstaller、-F -w等打包方式生成 exe 后,都出现错误,是怎么回事?