Skip to content

Commit

Permalink
Merge pull request #40 from tobias47n9e/master
Browse files Browse the repository at this point in the history
Add example for PyGTK with Matplotlib and Numpy
  • Loading branch information
takluyver committed Mar 9, 2015
2 parents b164e61 + bb4f380 commit 86a8989
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ with different frameworks:
- `A tkinter application <https://github.com/takluyver/pynsist/tree/master/examples/tkinter>`_
- `A PyQt4 application <https://github.com/takluyver/pynsist/tree/master/examples/pyqt>`_
- `A PyGTK application <https://github.com/takluyver/pynsist/tree/master/examples/pygtk>`_
- `A PyGTK application including Numpy and Matplotlib (32 bit, Python 2.7) <https://github.com/takluyver/pynsist/tree/master/examples/pygtk_mpl_numpy>`_
- `A pygame application <https://github.com/takluyver/pynsist/tree/master/examples/pygame>`_

Real-world examples
Expand Down
1 change: 1 addition & 0 deletions examples/build_all_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
'tkinter/installer.cfg',
'pygame/installer.cfg',
'pygtk/installer.cfg',
'pygtk_mpl_numpy/installer.cfg',
]

examples_dir = os.path.dirname(os.path.abspath(__file__))
Expand Down
101 changes: 101 additions & 0 deletions examples/pygtk_mpl_numpy/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
This is an example of building a Windows installer for a pygtk application that
includes matplotlib and numpy.

Requirements
------------

This example needs 7zip in order to work. You can install it for example on
Debian-style distributions using:

::

sudo apt-get install p7zip

Running the Example
-------------------

In order to build the example application on Linux you have to run the following
two commands in the example directory:

::

sh grab_files.sh
python -m nsist installer.cfg

The first line will download the dependencies, extract them and copy them into
the :code:`pynsist_pkgs`-directory. It will then remove the temporary directories
used for extraction, but will leave the downloaded archives intact in the
example directory.

Matplotlib
----------

The example downloads the 32-bit Python 2.7 bindings of Matplotlib 1.4.3
(matplotlib-1.4.3.win32-py2.7.exe).

In the :code:`installer.cfg` Matplotlib additionally requires the six, dateutil
and pyparsing packages:

::

[Include]
packages=pygtk
numpy
matplotlib
six
dateutil
pyparsing

Numpy
-----

The example downloads the 32-bit Python 2.7 bindings of Numpy 1.9.2
(numpy-1.9.2-win32-superpack-python2.7.exe).

PyGTK
-----

PyGTK is a bit more complex than the other examples, because the GTK runtime
needs to be set up. This needs two things:

1. The pieces of the GTK runtime and its Python bindings. The script ``grab_files.sh``
downloads these, unpacks them, trims out unnecessary pieces, and places them
where pynsist will find them.
2. The ``PATH`` environment variable must be modified before we try to import
the Python GTK bindings. This is done by the ``extra_preamble`` field in
``installer.cfg``.

I referred to the following sources of information to work this out:

Bundling pygtk using py2exe:
http://faq.pygtk.org/index.py?file=faq21.005.htp&req=show
https://web.archive.org/web/20060208162511/http://www.anti-particle.com/py2exe-0.5.shtml

Installing pygtk & deps: http://www.pygtk.org/downloads.html
(inc links for pygtk, pycairo and pygobject installers)

GTK bundles for Windows: http://www.gtk.org/download/win32.php

Installer.cfg
-------------

The example is customized for 32-bit and Python 2.7. This is expressed in the
:code:`installer.cfg`-file like this:

::

version=2.7.9
bitness=32

The include section requires pygtk, numpy and matplotlib. In order to satisfy the
requirements of Matplotlib the packages six, dateutil, and pyparsing are needed.

::

[Include]
packages=pygtk
numpy
matplotlib
six
dateutil
pyparsing
56 changes: 56 additions & 0 deletions examples/pygtk_mpl_numpy/grab_files.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Download the necessary files
wget -O gtkbundle.zip http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip
wget -O pygobject.exe http://ftp.gnome.org/pub/GNOME/binaries/win32/pygobject/2.28/pygobject-2.28.3.win32-py2.7.exe
wget -O pycairo.exe http://ftp.gnome.org/pub/GNOME/binaries/win32/pycairo/1.8/pycairo-1.8.10.win32-py2.7.exe
wget -O pygtk.exe http://ftp.gnome.org/pub/GNOME/binaries/win32/pygtk/2.24/pygtk-2.24.0.win32-py2.7.exe
wget -O numpy.exe http://downloads.sourceforge.net/project/numpy/NumPy/1.9.2/numpy-1.9.2-win32-superpack-python2.7.exe
wget -O matplotlib.exe https://downloads.sourceforge.net/project/matplotlib/matplotlib/matplotlib-1.4.3/windows/matplotlib-1.4.3.win32-py2.7.exe

# GTK runtime
mkdir gtkbundle
unzip -d gtkbundle gtkbundle.zip
cd gtkbundle
rm -r src man include share/doc share/man share/gtk-doc share/gtk-2.0/demo bin/gtk-demo.exe etc/bash_completion.d
cd ..

# Python bindings
mkdir pygobject
unzip -d pygobject pygobject.exe
mkdir pycairo
unzip -d pycairo pycairo.exe
mkdir pygtk
unzip -d pygtk pygtk.exe
mkdir numpy
unzip -d numpy numpy.exe
mkdir matplotlib
unzip -d matplotlib matplotlib.exe

# Reassemble into pynsist_pkgs
echo -n "Assembling GTK files into pynsist_pkgs... "
rm -r pynsist_pkgs
mkdir pynsist_pkgs
mv gtkbundle pynsist_pkgs/gtk

cp -r pygobject/PLATLIB/* pynsist_pkgs
rm -r pygobject

cp -r pycairo/PLATLIB/* pynsist_pkgs
cp -r pycairo/DATA/lib/site-packages/cairo/* pynsist_pkgs/cairo
rm -r pycairo

cp -r pygtk/PLATLIB/* pynsist_pkgs
rm -r pygtk

cp -r matplotlib/PLATLIB/* pynsist_pkgs
rm -r matplotlib

#Unzip numpy into base directory
7z e numpy.exe
#Unzip the NoSSE package into the numpy directory
7z x numpy-1.9.2-nosse.exe -onumpy
cp -r numpy/PLATLIB/* pynsist_pkgs
rm -r numpy

rm -r pynsist_pkgs/gtk-2.0/tests

echo "done"
2 changes: 2 additions & 0 deletions examples/pygtk_mpl_numpy/gtk_preamble.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
os.environ['PATH'] += os.pathsep + os.path.join(pkgdir, 'gtk/lib') + \
os.pathsep + os.path.join(pkgdir, 'gtk/bin')
42 changes: 42 additions & 0 deletions examples/pygtk_mpl_numpy/hellomatplotlib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python

# This example was adapted from http://matplotlib.org/examples/user_interfaces/embedding_in_gtk.html, and http://pygtk.org/pygtk2tutorial/examples/helloworld.py

import pygtk
pygtk.require('2.0')
import gtk
from matplotlib.figure import Figure
from numpy import arange, sin, pi
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas

class HelloMatplotlib:
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("delete_event", self.delete_event)
self.window.connect("destroy", self.destroy)
self.window.set_size_request(400, 400)
self.window.set_border_width(10)

f = Figure(figsize=(5,4), dpi=100)
a = f.add_subplot(111)
t = arange(0.0,3.0,0.01)
s = sin(2*pi*t)
a.plot(t,s)

self.canvas = FigureCanvas(f)
self.canvas.show()
self.window.add(self.canvas)
self.window.show()

def delete_event(self, widget, event, data=None):
gtk.main_quit()

def destroy(self, widget, data=None):
gtk.main_quit()

def main(self):
gtk.main()

def main():
hello = HelloMatplotlib()
hello.main()
17 changes: 17 additions & 0 deletions examples/pygtk_mpl_numpy/installer.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[Application]
name=Hello Matplotlib (PyGTK)
version=1.0
entry_point=hellomatplotlib:main
extra_preamble=gtk_preamble.py

[Python]
version=2.7.9
bitness=32

[Include]
packages=pygtk
numpy
matplotlib
six
dateutil
pyparsing

0 comments on commit 86a8989

Please sign in to comment.