【问题标题】:How to compile all resources into one executable file?如何将所有资源编译成一个可执行文件?
【发布时间】:2011-10-05 02:06:39
【问题描述】:

我已经用 python 编写了 GTK 应用程序。

所有图形用户界面都在 glade 文件中,并且使用了一些图像。我希望将我的应用程序编译成可执行文件。为此,我使用 PyInstaller 编译器和 UPX 打包器。

我已经按照手册说的做了:

python Configure.py
python Makespec.py --onefile --windowed --upx /path/to/yourscript.py
python Build.py /path/to/yourscript.spec

PyInstaller 完美运行并创建一个 exe 文件。但是为了使我的应用程序正常工作,我必须将我的 gladeimage 文件复制到 exe 的文件夹中。

有没有办法将这些文件编译成可执行文件?

我以各种方式编辑了我的规范文件,但我无法实现我想要的。下面的spec文件只拷贝文件到目录,不编译成可执行文件

# -*- mode: python -*-
a = Analysis([os.path.join(HOMEPATH,'support\\_mountzlib.py'), os.path.join(HOMEPATH,'support\\useUnicode.py'), 'r:\\connection\\main.py'],
             pathex=['C:\\Documents and Settings\\Lixas\\Desktop\\pyinstaller-1.5-rc1'])

pyz = PYZ(a.pure)

exe = EXE( pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name=os.path.join('dist', 'NetworkChecker.exe'),
          debug=False,
          strip=False,
          upx=True,
          console=False,
          icon='r:\\connection\\ikona.ico'        )

coll = COLLECT(
    exe,
    [('gui.glade', 'r:\\connection\\gui.glade', 'DATA')],
    [('question16.png', 'r:\\connection\\question16.png', 'DATA')],
#   a.binaries,
#   strip=False,
    upx=True,
    name='distFinal')

我希望只有一个包含所有内容的可执行文件

【问题讨论】:

    标签: python compiler-construction pygtk glade pyinstaller


    【解决方案1】:

    有没有办法将这些文件编译成可执行文件?

    严格来说:不,因为you compile source code,而glade 文件是XML,图像是二进制数据。您通常要做的是创建一个安装程序(即一个自解压存档,在运行安装程序时将不同的文件放置在正确的目录中)。

    编辑:如果您只是想拥有一个单一文件的可执行文件(所以它不是关于“编译”,而是关于永久写入文件系统的文件数量),您可以尝试在py2exe 的基础上使用this script。它的作用是在每次运行程序时创建临时文件,并在执行完成时将其删除。

    EDIT2:显然你所要求的也可以在PyInstaller 下实现。来自documentation

    默认情况下,pyinstaller.py 创建一个包含主要可执行文件和动态库的分发目录。选项 --onefile 指定您希望 PyInstaller 构建一个包含所有内容的单个文件。

    【讨论】:

    • 我希望做一个超便携的应用程序,你只需要担心一个文件。但如果这种方式不可能——我会尝试将图像和空地文件实现到 python 脚本代码中。 非常感谢也许其他人对我的问题有任何其他意见
    • @Lixas - 我真的不明白你为什么要走这条路(我不是批评:我要求澄清,因为我看不到它对用户的好处,虽然我可以看到它的缺点)。但是,如果您关心的是文件的 数量 而不是它们可执行的事实,请参阅我的编辑,我在其中链接了一个脚本,该脚本几乎可以满足您的要求,如果我得到了正确的文档.
    • 您或许可以帮我解决我的problem
    【解决方案2】:

    通过一些更改,您可以将所有内容合并到您的源代码中,从而合并到您的可执行文件中。

    如果您在图像文件上运行gdk-pixbuf-csource,您可以将它们转换为字符串,然后您可以使用gtk.gdk.pixbuf_new_from_inline() 加载。

    您还可以将 Glade 文件作为字符串包含在程序中,然后使用 gtk.Builder.add_from_string() 加载它。

    【讨论】:

    • 这是我之前想到的想法——将资源合并到脚本中。感谢您为我指出如何将资源合并到应用程序 exe 文件中。
    • +1 因为根据 OP 的 cmets,这使得获得他想要的东西成为可能。不过,我仍然想了解将所有内容放在单个运行时文件中的好处是什么……但这当然不是您回答的问题! :)
    • 你或许能帮我解决我的problem
    【解决方案3】:

    PyInstaller 确实允许您将所有资源捆绑到 exe 中,而无需将数据文件转换为 .py 文件的棘手问题——您的 COLLECT 对象似乎是正确的,棘手的步骤是访问这些文件在运行时。 PyInstaller 会将它们解压缩到一个临时目录中,并通过 _MEIPASS2 变量告诉你它们在哪里。为了在开发和打包模式下获取文件路径,我使用这个:

    def resource_path(relative):
        return os.path.join(
            os.environ.get(
                "_MEIPASS2",
                os.path.abspath(".")
            ),
            relative
        )
    
    
    # in development
    >>> resource_path("gui.glade")
    "/home/shish/src/my_app/gui.glade"
    
    # in deployment
    >>> resource_path("gui.glade")
    "/tmp/_MEI34121/gui.glade"
    

    【讨论】:

    • 这不再是环境变量,现在存储在sys._MEIPASS
    • @favilo:您能告诉我们这将如何更改此代码以使其正常工作吗?
    • 你或许能帮我解决我的problem
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    • 1970-01-01
    相关资源
    最近更新 更多