在py2exe打包的PyGTK程序中显示图像
我用Python和PyGTK写了一个图形界面应用程序,现在想把它打包成一个可执行文件,所以我在用py2exe。可是当我运行我的程序时,出现了以下警告:
GdkPixbuf-WARNING **: Cannot open pixbuf loader module file 'gtk-2.0\gdk-pixbuf.loaders': No such file or directory
而且我的图片没有显示出来,尽管dist\etc\gtk-2.0\gdk-pixbuf.loaders
这个文件夹是存在的。
我该怎么把我的程序打包成Windows的exe文件,并且使用这些图片呢?
2 个回答
把GTK+的bin、etc、share和lib文件夹复制到项目的dist目录下,这个做法是对的(不过我看到有人把[1]搞乱了,bin这个文件夹在列表里缺失了)。毕竟:
- PyGTK其实就是一个薄薄的层,把GTK+提供给Python用。
- PyGObject也是一个薄薄的层,把GObject、GIO等提供给Python用。
- PyCairo同样是一个薄薄的层,把Cairo提供给Python用。
至少,你需要这三个绑定包,而由于它们的特性,如果底层平台不可用(比如.dll文件、配置文件,简单来说就是所有相关文件),它们就没什么用。这就是为什么需要把GTK+的bin、etc、share和lib复制到你的项目dist目录里的原因。
不过,我几年前发到[1]的setup.py片段有点不完整。正确的版本应该是:
from distutils.core import setup
import py2exe
setup(
name = 'handytool',
description = 'Some handy tool',
version = '2.0',
zipfile = 'bin/library.zip',
windows = [{'script': 'handytool.py',
'dest_base': 'bin/handytool'}
],
options = {'py2exe': {'packages':'encodings',
'includes': 'glib, gio, gobject, cairo, atk, pango, pangocairo, gtk'}
}
)
注意zipfile和dest_base的值。使用这些选项后,你的.exe文件、一堆.pyd文件和library.zip都会在py2exe的dist/bin目录下生成。然后,当你把GTK+的文件夹复制到py2exe的dist目录时,你的可执行文件就会和libgtk-win32-2.0.0.dll等文件放在一起,这样才对。如果不这样做,配置不当的PATH环境变量可能会干扰你的py2exe可执行文件加载的(有时不兼容的).dll文件。
所以,对于上面的setup.py文件,dist的正确目录结构应该是这样的:
bin/handytool.exe
bin/library.zip
bin/*.pyd (all .pyd files py2exe deemed needed)
bin/* (complete copy of GTK+ runtime bin dir)
etc/* (complete copy of GTK+ runtime etc dir)
share/* (complete copy of GTK+ runtime share dir)
lib/* (complete copy of GTK+ runtime lib dir)
当你把上面的内容正确设置好后,你会发现加载图片就能正常工作了,这时你可以开始考虑去掉share/中的一些部分(比如你不想要或不需要的翻译文件)等等。
祝好,
Dieter
[1] http://www.py2exe.org/index.cgi/Py2exeAndPyGTK
编辑 2011/07/05:修正了PyGObject 2.28/PyGTK 2.24的includes选项。如果你只使用PyGObject 2.28,includes选项需要包含'glib, gio, gobject'。如果你使用PyGTK,则需要包含:'glib, gio, gobject, cairo, atk, pango, pangocairo, gtk'。
如果你在使用py2exe工具,你需要把gtk+(还有其他共享库和文件)放在你的项目里,和你的exe文件放在同一个层级:
下面是一个示例的文件夹结构:
PROGRAM.exe
LOT_OF_PYD_AND_LIB_FILES...
etc
etc\fonts
etc\gtk-2.0
etc\pango
lib
lib\gtk-2.0
share
share\aclocal
share\glib-2.0
share\locale
share\themes
你有这样的文件夹结构吗?