Pyinstaller和--onefile:如何在exe文件中包含图像

时间:2015-08-05 15:00:27

标签: python pyinstaller

我使用Pyinstaller创建了一个exe文件。

pyinstaller.exe --onefile --icon='Loco.ico program.py

在程序中,我在我的图中包含了一个图像,当我在其文件夹中单独运行程序时,我得到以下内容:

IOError: [Errno 2] No such file or directory: 'Logo.png'

一种解决方案是将图像包含在exe文件夹中,如下面的链接所示:

pyinstaller does not show images and icon

但是再一次--onefile的全部要点就是这样,不需要图像了。我认为解决方案可能在这个链接中,但我还没有理解它。

Bundling data files with PyInstaller (--onefile)

我的spec文件看起来如下:

# -*- mode: python -*-
a = Analysis(['AMOS_Visualizer.py'],
    pathex=['C:\\Users\\elu\\PycharmProjects\\Prosjektet\\Forsok splitting'],
    hiddenimports=[],
    hookspath=None,
    runtime_hooks=None)

pyz = PYZ(a.pure)
exe = EXE(pyz,
      a.scripts,
      a.binaries,
      a.zipfiles,
      a.datas,
      name='AMOS_Visualizer.exe',
      debug=False,
      strip=None,
      upx=True,
      console=True , icon='AMOS.ico')

8 个答案:

答案 0 :(得分:11)

编辑:

我相信我找到了解决问题的方法。

# -*- mode: python -*-
a = Analysis(['AMOS_Visualizer.py'],
         pathex=['C:\\Users\\elu\\PycharmProjects\\Prosjektet\\Forsok splitting'],
         hiddenimports=[],
         hookspath=None,
         runtime_hooks=None)

for d in a.datas:
    if 'pyconfig' in d[0]:
        a.datas.remove(d)
        break

a.datas += [('Logo.png','C:\\Users\\elu\\PycharmProjects\\Prosjektet\\Forsok splitting\\Logo.png', 'Data')]
pyz = PYZ(a.pure)
exe = EXE(pyz,
      a.scripts,
      a.binaries,
      a.zipfiles,
      a.datas,
      name='AMOS_Visualizer.exe',
      debug=False,
      strip=None,
      upx=True,
      console=True, icon='C:\\Users\\elu\\PycharmProjects\\Prosjektet\\Forsok splitting\\AMOS.ico')

将以下内容添加到我的main.py脚本

def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    try:
        # PyInstaller creates a temp folder and stores path in _MEIPASS
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

Logo = resource_path("Logo.png")

答案 1 :(得分:1)

如果您使用Qt Designer,可以通过创建资源文件并将所需的所有图像(包括Logo.png)添加到此资源来实现。

要创建资源文件,您可以按照Inserting an image in GUI using QT Designer中的步骤进行操作。

在资源文件中插入图像后,将Logo.png指定给Window图标,保存QtDesigner界面并使用以下命令转换资源文件:pyrcc4 -py3 resourcetest.qrc -o resourcetest_rc.py

最后,使用--onefile选项创建exe文件。无需编辑规范文件。

答案 2 :(得分:1)

添加"数据= ['您文件的位置'],"之前" hiddenimports = []"。它会的。 在我的情况下,这工作

    # -*- mode: python -*-

block_cipher = None


a = Analysis(['embed.py'],
             pathex=['C:\\Users\\Aravind\\Desktop\\exe'],
             binaries=[],
             datas=['C:\\Users\\Aravind\\Desktop\\exe\\dist\\map.png'],
             hiddenimports=[],
             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,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='embed',
          debug=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=True )

答案 3 :(得分:0)

这是以下内容的变体: Bundling data files with PyInstaller (--onefile), 并且给出的答案更清楚。

分为两行:

  1. 您必须在"数据"中添加您的图像文件。 (在您的规格中 文件或使用PyInstaller钩子脚本)
  2. 如果是,请使用sys._MEIPASS 存在,
    使用单行base_path = getattr(sys, '_MEIPASS', '.')+'/'获取" root_path"变量连接到你的所有 文件'路径。
    然后,filepath = base_path + filepath

答案 4 :(得分:0)

我已经尝试了很多,但是一个小时后就奏效了

当我第一次运行程序文件MilaBild.py时:

o -> o.name

通过接缝创建“ .spec”文件,我需要在上面的其他注释中添加以下内容:

pyinstaller -F -w MilaBild.py

我的图像文件的名称是rosa.png。它位于与我的程序文件MilaBild.py相同的目录中。

然后,我不得不在我的实际程序文件中添加上面注释中提到的上述部分:

a.datas += [('rosa.png','C:\\Python34\\rosa.png', 'DATA')]

然后我在将文件添加到变量的部分中添加了它,并且起作用了:

def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
    # PyInstaller creates a temp folder and stores path in _MEIPASS
    base_path = sys._MEIPASS
except Exception:
    base_path = os.path.abspath(".")

return os.path.join(base_path, relative_path)

我做了很多尝试,只是为了使这项工作花了我一个小时。稍后,我将尝试使用两个图像,声音和子目录来实现。但是现在现在是23:45,这将是另一天,我对如此巨大的突破槽感到非常满意。

答案 5 :(得分:0)

最后,它比我在各种网页和此处所找到的要简单。

1)当代码作为已编译的可执行文件运行时,您可以在代码中指定临时目录中的相对路径:

if getattr(sys, 'frozen', False): # Running as compiled
    running_dir = sys._MEIPASS + "/files/" # Same path name than pyinstaller option
else:
    running_dir = "./" # Path name when run with Python interpreter
iconFileName = running_dir + "mylogo.ico"
if os.path.isfile(iconFileName):
    root.iconbitmap(iconFileName) # Exemple for tkinter usage

2)您在创建的临时目录中提供路径,该目录将在编译器选项上存储文件:

pyinstaller --onefile --add-binary "mylogo.ico;files" -i mylogo.ico myMainPrg.py

这样,您不必知道文件正在开发中以及要在生产环境中安装文件的完整路径。

答案 6 :(得分:0)

为此苦恼。要知道的关键是,对于 --onefile 构建,您的图像存储在 sys._MEIPASS 文件夹中。

我的 tkinter 应用程序中的这行代码破坏了我的 .exe:

self.wm_iconbitmap("favicon.ico")

为了修复它,我用这个替换了它:

self.wm_iconbitmap(get_path("favicon.ico"))

其中 get_path() 是我添加到模块中的一个小函数:

def get_path(filename):
    if hasattr(sys, "_MEIPASS"):
        return f'{os.path.join(sys._MEIPASS, filename)}'
    else:
        return f'{filename}'

对于上下文,我在 CLI 中运行此命令来构建 .exe:

pyinstaller --noconfirm --onefile --windowed --add-data "C:/Users/[...]/favicon.ico;."  "C:/Users/[...]/main.py"

注意,在 Win10 上运行。

感谢许多其他 Stack Overflow 贡献者。

答案 7 :(得分:-3)

什么都不担心。我有同样的问题,只是这样做就得到了答案... 复制我的所有图像并将其粘贴到pyinstaller创建的dist /和build /目录中,问题已解决。 :)