使用 py2exe 捆绑 GTK 资源 [英] Bundling GTK resources with py2exe

查看:49
本文介绍了使用 py2exe 捆绑 GTK 资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 中的 Python 2.6 和 PyGTK 2.22.6Windows XP 上的多合一安装程序,尝试构建单文件可执行文件(通过 py2exe>) 用于我的应用.

I'm using Python 2.6 and PyGTK 2.22.6 from the all-in-one installer on Windows XP, trying to build a single-file executable (via py2exe) for my app.

我的问题是,当我将我的应用程序作为脚本运行时(即没有内置在 .exe 文件中,只是作为 .py 文件的松散集合),它使用原生的 Windows 主题,但是当我运行构建的 exe 时,我看到了默认的 GTK 主题.

My problem is that when I run my app as a script (ie. not built into an .exe file, just as a loose collection of .py files), it uses the native-looking Windows theme, but when I run the built exe I see the default GTK theme.

我知道可以通过将一堆文件复制到 py2exe 创建的 dist 目录中来解决这个问题,但是我读过的所有内容都涉及手动复制数据,而我希望这是构建过程的一个自动部分.此外,关于该主题的所有内容(包括 常见问题解答) 已过时 - PyGTK 现在将其文件保存在 C:\Python2x\Lib\site-packages\gtk-2.0\runtime\...,并且只需复制 libetc 目录不能解决问题.

I know that this problem can be fixed by copying a bunch of files into the dist directory created by py2exe, but everything I've read involves manually copying the data, whereas I want this to be an automatic part of the build process. Furthermore, everything on the topic (including the FAQ) is out of date - PyGTK now keeps its files in C:\Python2x\Lib\site-packages\gtk-2.0\runtime\..., and just copying the lib and etc directories doesn't fix the problem.

我的问题是:

  1. 我希望能够以编程方式在 setup.py 中找到 GTK 运行时数据,而不是硬编码路径.我该怎么做?

  1. I'd like to be able to programmatically find the GTK runtime data in setup.py rather than hard coding paths. How do I do this?

我需要包含的最少资源是什么?

What are the minimal resources I need to include?

更新:我可能几乎通过反复试验来回答 #2.要使wimp"(即 MS Windows)主题工作,我需要以下文件:

Update: I may have almost answered #2 by trial-and-error. For the "wimp" (ie. MS Windows) theme to work, I need the files from:

runtime\lib\gtk-2.0\2.10.0\engines\libwimp.dll
runtime\etc\gtk-2.0\gtkrc
runtime\share\icons\*
runtime\share\themes\MS-Windows

...没有 runtime 前缀,但在其他方面具有相同的目录结构,直接位于 py2exe 生成的 dist 目录中.但是 2.10.0 从哪里来,因为 gtk.gtk_version(2,22,0)?

...without the runtime prefix, but otherwise with the same directory structure, sitting directly in the dist directory produced by py2exe. But where does the 2.10.0 come from, given that gtk.gtk_version is (2,22,0)?

推荐答案

在这里回答我自己的问题,但如果有人知道更好,也可以随意回答.其中一些看起来很脆弱(例如路径中的版本号),如果您知道更好的方法,请进行评论或编辑.

Answering my own question here, but if anyone knows better feel free to answer too. Some of it seems quite fragile (eg. version numbers in paths), so comment or edit if you know a better way.

首先,我使用这段代码来实际找到 GTK 运行时的根.不过,这与您安装运行时的方式非常相关,并且可能会通过对常见位置的大量检查来改进:

Firstly, I use this code to actually find the root of the GTK runtime. This is very specific to how you install the runtime, though, and could probably be improved with a number of checks for common locations:

#gtk file inclusion
import gtk
# The runtime dir is in the same directory as the module:
GTK_RUNTIME_DIR = os.path.join(
    os.path.split(os.path.dirname(gtk.__file__))[0], "runtime")

assert os.path.exists(GTK_RUNTIME_DIR), "Cannot find GTK runtime data"

2.要包含哪些文件

这取决于 (a) 关注点的大小,以及 (b) 应用程序部署的上下文.我的意思是,您是将它部署到任何人都可以拥有任意区域设置的整个世界,还是仅用于不需要翻译的股票字符串的公司内部使用?

2. What files to include

This depends on (a) how much of a concern size is, and (b) the context of your application's deployment. By that I mean, are you deploying it to the whole wide world where anyone can have an arbitrary locale setting, or is it just for internal corporate use where you don't need translated stock strings?

如果您想要 Windows 主题,则需要包括:

If you want Windows theming, you'll need to include:

GTK_THEME_DEFAULT = os.path.join("share", "themes", "Default")
GTK_THEME_WINDOWS = os.path.join("share", "themes", "MS-Windows")
GTK_GTKRC_DIR = os.path.join("etc", "gtk-2.0")
GTK_GTKRC = "gtkrc"
GTK_WIMP_DIR = os.path.join("lib", "gtk-2.0", "2.10.0", "engines")
GTK_WIMP_DLL = "libwimp.dll"

如果您想要 Tango 图标:

If you want the Tango icons:

GTK_ICONS = os.path.join("share", "icons")

还有本地化数据(我省略了,但您可能不想):

There is also localisation data (which I omit, but you might not want to):

GTK_LOCALE_DATA = os.path.join("share", "locale")

3.拼凑起来

首先,这是一个在给定点遍历文件系统树并产生适合的输出的函数data_files 选项.

def generate_data_files(prefix, tree, file_filter=None):
    """
    Walk the filesystem starting at "prefix" + "tree", producing a list of files
    suitable for the data_files option to setup(). The prefix will be omitted
    from the path given to setup(). For example, if you have

        C:\Python26\Lib\site-packages\gtk-2.0\runtime\etc\...

    ...and you want your "dist\" dir to contain "etc\..." as a subdirectory,
    invoke the function as

        generate_data_files(
            r"C:\Python26\Lib\site-packages\gtk-2.0\runtime",
            r"etc")

    If, instead, you want it to contain "runtime\etc\..." use:

        generate_data_files(
            r"C:\Python26\Lib\site-packages\gtk-2.0",
            r"runtime\etc")

    Empty directories are omitted.

    file_filter(root, fl) is an optional function called with a containing
    directory and filename of each file. If it returns False, the file is
    omitted from the results.
    """
    data_files = []
    for root, dirs, files in os.walk(os.path.join(prefix, tree)):        
        to_dir = os.path.relpath(root, prefix)

        if file_filter is not None:
            file_iter = (fl for fl in files if file_filter(root, fl))
        else:
            file_iter = files

        data_files.append((to_dir, [os.path.join(root, fl) for fl in file_iter]))

    non_empties = [(to, fro) for (to, fro) in data_files if fro]

    return non_empties

所以现在你可以像这样调用 setup() :

So now you can call setup() like so:

setup(
    # Other setup args here...

    data_files = (
                    # Use the function above...
                    generate_data_files(GTK_RUNTIME_DIR, GTK_THEME_DEFAULT) +
                    generate_data_files(GTK_RUNTIME_DIR, GTK_THEME_WINDOWS) +
                    generate_data_files(GTK_RUNTIME_DIR, GTK_ICONS) +

                    # ...or include single files manually
                    [
                        (GTK_GTKRC_DIR, [
                            os.path.join(GTK_RUNTIME_DIR,
                                GTK_GTKRC_DIR,
                                GTK_GTKRC)
                        ]),

                        (GTK_WIMP_DIR, [
                            os.path.join(
                                GTK_RUNTIME_DIR,
                                GTK_WIMP_DIR,
                                GTK_WIMP_DLL)
                        ])
                    ]
                )
)

这篇关于使用 py2exe 捆绑 GTK 资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆