[:en]Tales of a GeekTrotter[:fr]Récits d'un GeekTrotter[:ja]Tales of a GeekTrotter [:en]Binary Logbook[:fr]Carnet de bord binaire[:ja]ギークの旅行

1Déc/110

Package a Python Qt (PySide) application for Windows (.exe)Empaqueter un programme Python Qt (PySide) sous Windows (.exe)

That's fairly easy to package a Python Qt (PySide) application for Windows (and even easier on Linux with cxfreeze).

Let see two different ways of doing so.

C'est assez simple de créer des exécutables de programmes Python utilisant le framework de GUI Qt (PySide) sous Windows (et encore plus simple sous Linux avec cxfreeze).

Voyons deux façon de faire.

1. py2exe

Pros

  • Easy
  • Support multiple binaries

Cons

  • Might miss some dependencies

Download

Py2Exe Website
There are binaries for both win32 and win64.

Basic setup

basic_setup.py

from distutils.core import setup
import py2exe

setup(
    windows = ['pysideApp1.py','pysideApp2.py'],
    options = {
        "py2exe" : {
            "includes" : ['sys', 'tempfile', 'zipfile', 'mmap', 'encodings',
                          'json', 'hashlib', 'datetime', 'struct',
                          'os', 'time', 'random', 'math', 'xmlrpclib', 'Crypto']
        }
    }
)

Compile

$ python basic_setup.py py2exe

That's it!
Look in your "dist" folder and you should have your application 😉

2. PyInstaller

Pros

  • Seems to detect the required libraries much better

Cons

  • Last stable version (1.5.1 as today) does not support multiple binaries
  • Need a little more config

Download

PyInstaller Website
No need to install, just extract somewhere.

PySide setup

pyside.spec

import os

a = Analysis(
    [os.path.join(HOMEPATH,'support\\_mountzlib.py')
        , os.path.join(HOMEPATH,'support\\useUnicode.py')
        , os.path.normpath(os.path.join(currentDir, 'main.py'))
        , os.path.normpath(os.path.join(currentDir, 'importantLib.py'))
        # add the files you want PyInstaller to analyse the "import" statements
        # to detect the libraries to include
    ],
     pathex=['C:\\Python27\\pyinstaller-1.5.1']
)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=1,
          name=os.path.join('build\\pyi.win32\\build_output', 'your_application.exe'),
          debug=False,
          strip=False,
          upx=True,
          console=False )
coll = COLLECT( exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name=os.path.join('dist', 'dist_output'))

Compile

Move to your pyinstaller.py location and run:
$ python pyinstaller.py "C:\path\to\pyside.spec"

That's it!
Look in your "dist_output" folder and you should have your application 😉

Postface

Both methods work fine.
The output folder with PyInstaller is a little bigger (~10MB, whereas the one with py2exe is ~8MB).
However, it seems to include more libraries, even though I didn't manually specified any specific library, I just gave the 2 main py files of my program, so maybe more reliable.

1. py2exe

Avantages

  • Facile
  • Supporte plusieurs exécutables

Désavantage

  • Oublie parfois des bibliothèques

Téléchargement

Site de Py2Exe
Il existe des exécutables pour 32 et 62 bits.

Configuration basique

basic_setup.py

from distutils.core import setup
import py2exe

setup(
    windows = ['pysideApp1.py','pysideApp2.py'],
    options = {
        "py2exe" : {
            "includes" : ['sys', 'tempfile', 'zipfile', 'mmap', 'encodings',
                          'json', 'hashlib', 'datetime', 'struct',
                          'os', 'time', 'random', 'math', 'xmlrpclib', 'Crypto']
        }
    }
)

Compiler

$ python basic_setup.py py2exe

Et c'est tout !
Admirez votre répertoire "dist" et vous devriez avoir votre application 😉

2. PyInstaller

Avantage

  • Semble mieux détecter les bibliothèques nécessaires

Désavantages

  • La dernière version stable à ce jour (1.5.1) ne supporte pas plusieurs fichiers exécutables
  • Requiert un peu plus de configuration

Téléchargement

Site de PyInstaller
Pas besoin d'installer, extrayez juste quelque part.

Configuration pour PySide

pyside.spec

import os

a = Analysis(
    [os.path.join(HOMEPATH,'support\\_mountzlib.py')
        , os.path.join(HOMEPATH,'support\\useUnicode.py')
        , os.path.normpath(os.path.join(currentDir, 'main.py'))
        , os.path.normpath(os.path.join(currentDir, 'importantLib.py'))
        # add the files you want PyInstaller to analyse the "import" statements
        # to detect the libraries to include
    ],
     pathex=['C:\\Python27\\pyinstaller-1.5.1']
)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=1,
          name=os.path.join('build\\pyi.win32\\build_output', 'your_application.exe'),
          debug=False,
          strip=False,
          upx=True,
          console=False )
coll = COLLECT( exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name=os.path.join('dist', 'dist_output'))

Compile

Allez dans le dossier où vous avez extrait PyInstaller et lancez:
$ python pyinstaller.py "C:\chemin\vers\pyside.spec"

C'est tout !
Regardez votre répertoire "dist_output" et vous devriez avoir votre programme 😉

Postface

Les deux méthodes marchent bien.
Le dossier créé par PyInstaller est un peu plus gros (environ 10MB dans mon cas pour 8MB avec py2exe).
Cependant, il semble include plus de bibliothèques, alors que je n'ai manuellement spécifié aucune bibliothèque spéciale (alors que je l'avais fait pour py2exe).
Je n'ai spécifié que mes 2 fichiers .py principaux et il a trouvé toutes les bibliothèques nécessaires comme un grand, c'est donc peut-être plus fiable.