[PyQt] Compiling PyQt4 in windows for smaller Qt footprint

Giovanni Bajo rasky at develer.com
Sun Dec 7 11:32:38 GMT 2008

On sab, 2008-12-06 at 23:51 -0200, Nahuel Defossé wrote:
> Hi
> my main development platform is linux, but I have to deliver win32 binaries 
> from time to time. I build them with py2exe and sometimes with PyInstaller, 
> but no matter which of them I use, it turns out that the minimum QtGui + 
> QtCore exe application footprint is 23MB. At least using the PyQt4 msi 
> installer available at riverbankcomputing.co.uk

Did you try installing UPX and reconfiguring PyInstaller to use it?
Also, you can patch PyInstaller's Build.py file to run UPX with --lzma
instead of --best, as it gives better results.

> There are compressors for exe's and dll's, but I wanted to attack the root of 
> the problem, PyQt4 size itself so I've asked in my local python maling 
> list[1] (Spanish) and they told me that I could recompile PyQt4 disabling 
> things I don't use. Is that possible? Any advise/article/anything regarding 
> to this subject?

Yes it is possible. Typically, for a PyQt application, you might want

 * Avoid including the East-Asian codecs (a couple of megs of
non-compressible tables) twice: they're both within Python and Qt.
Stripping them out of Python is easy: just recompile Python DLL and
comment out the builtin cjkcodecs module; and since you're at it, you
can strip loads of other builtin modules you don't use. Once you did it,
it is sufficient to copy the python DLL next to your boot module (the
one you run to start the application) to have PyInstaller pick it up in
place of the standard one.

 * Compile PyQt in solid mode, which means that all the code (both Qt's
and PyQt's) gets compiled within a single _qt.pyd module. This saves
loads of megs because of the large import/export tables that aren't
needed anymore (using non-solid mode, they are need to make PyQt
dynamically link with Qt's DLL). You don't need to touch the
application: your imports will still "magically" work thanks to SIP.
Just configure PyQt using --consolidate, and activate the modules you're
using (eg: --enable QtCore --enable QtGui). Moreover, you will also need
to compile the plugins you use (eg: --plugin qjpeg if your application
needs to load jpegs).

To give you a figure, a _qt.pyd with QtCore, QtGui, QtOpenGL, QtSvg and
Qt3Support, with plugins for JPG and SVG, is less than 3Mb after
compression with upx --lzma. A stripped down python25.dll is surely less
than 1Mb after compression. So a PyQt4 "hello-world" would be around

As a final note, remember to run PyInstaller's ArchiveViewer.py over the
final executable to list all the contents. There might be some packages
(binaries or bytecodes) that get included because of some optional
dependency and that you might explicitly exclude by manually populating
the "excludes" list in your .spec file.
Giovanni Bajo
Develer S.r.l.

More information about the PyQt mailing list