开发者

Displaying images in a py2exe'd PyGTK program

I have written a GUI app in Python using PyGTK and want to distribute it as an executable, for which I'm using py2exe. When I run my program, I get the following warning

GdkPixbuf-WARNING **: Cannot open pixbuf loader module file 'gtk-2.0\gdk-pixbuf.loaders': No such file or directory

and my images do not display, even though dist\etc\gtk-2.0\gdk-pixbuf.loaders exists.

How can I package m开发者_高级运维y program as a Windows exe and use these imagines?


If you are using py2exe, you must pack gtk+ (etc, shared, lib) inside your project at the same level of your exe:

Sample directory structure:

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

Do you have that directory structure?


The standard answer of copying GTK+'s bin, etc, share and lib directory to the project's dist directory is correct (but I see somebody has vandalized [1] and bin is missing from the list), after all:

  • PyGTK is nothing more than a thin layer of glue making GTK+ available to Python
  • PyGObject is nothing more than a thin layer of glue making GObject, GIO, ... available to Python
  • PyCairo is nothing more than a thin layer of glue making Cairo available to Python

At a minimum, you need all 3 of those bindings packages and due to their nature they are useless if the underlying platform is not available (.dll files, configuration files, in short: the whole shebang). That's why GTK+'s bin, etc, share and lib need to be copied to your project's dist directory.

The setup.py fragment I posted a couple of years ago to [1] is however subtly incomplete. The correct version should have been:

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'}
              }
)

Take note of the values for zipfile and dest_base. With these options your .exe, a bunch of .pyd files and library.zip are all created in py2exe's dist/bin directory. Then when you copy GTK+'s directories to py2exe's dist directory your executable lives right next to libgtk-win32-2.0.0.dll et al as it should be. If you don't do the above, a misconfigured PATH environment variable might interfere with what (sometimes incompatible) .dll files your py2exe'd executable loads.

So for the above setup.py file, the correct directory structure of dist should look like this:

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)

When you get the above working correctly you will find that loading images just works and you can start thinking about leaving out some parts of share/ (like the translation files you don't want/need) etc.

mvg, Dieter

[1] http://www.py2exe.org/index.cgi/Py2exeAndPyGTK

Edit 2011/07/05: fixed the includes option for PyGObject 2.28/PyGTK 2.24. If you're only using PyGObject 2.28 the includes option has to contain 'glib, gio, gobject'. If you're using PyGTK then it needs: 'glib, gio, gobject, cairo, atk, pango, pangocairo, gtk'.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜