Outils pour utilisateurs

Outils du site


cx_freeze_pyqt4_linux

Diffusion de programmes PyQt4 autonomes sous Linux grâce à cx_freeze

Problématique

Faire un joli programme qui marche est une (bonne) chose, le diffuser en est une autre.

Il faut en effet que le PC du nouvel utilisateur dispose déjà des programmes nécessaires de Python, de PyQt4 (, etc…), avec les bonnes versions, sans lesquels votre programme ne fonctionnera pas (et vous porterez le chapeau…).

Alors, il est important de pouvoir diffuser votre programme, accompagné de toutes les bibliothèques qui lui permettront de fonctionner correctement, même si l'utilisateur n'a rien installé du tout! C'est l'objet du présent tuto.

On va utiliser le logiciel cx_freeze pour cela (http://cx-freeze.sourceforge.net/). Il a l'avantage d'être multiplateforme (Windows-Linux). Il faudra bien sûr l'utiliser sous Windows pour avoir la version Windows et sous Linux pour avoir la version Linux, car les bibliothèques ne sont pas les mêmes.

On va étudier ici l'utilisation de cx_freeze sur Ubuntu 10.10, une des distributions Linux les plus utilisées.

Utilisation de cx_freeze sur Ubuntu 10.10

Pour mettre au point ce tuto, j'ai installé deux Ubuntu 10.10:

  • l'un que j'ai laissé “brut d'install”,
  • et l'autre sur lequel j'ai installé tout ce qu'il fallait pour faire fonctionner un programme Python-PyQt4 complexe (avec QtSql).

Mon but est de pouvoir transporter sur la version “brute d'install”, le programme traité par cx_freeze.

Que faut-il installer pour qu'un programme PyQt4 fonctionne?

Ubuntu 10.10 est installé avec Python 2.6.6. Il est possible d'installer Python 2.7, voire Python 3.1, mais je ne l'ai pas fait par prudence: certains autres programmes, y compris du système, fonctionnent avec la version de Python pré-installée.

Pour qu'un programme PyQt4 fonctionne, il faut peu de choses:

  • python-qt4

Il faut, bien sûr ajouter les autres modules utilisés par votre programme. Par exemple:

  • python-qt4-sql (accès aux bases de données SQL avec QtSql)
  • libqt4-sql-sqlite (driver SQL pour sqlite3. Il y en a d'autres pour mysql, postgresql, etc…)
  • python-qt4-phonon (multimedia)

Et c'est tout! Avec synaptic, c'est l'affaire de 2 minutes.

Une chose importante: en s'installant, python-qt4 installe aussi, au titre des dépendances, python-sip: il est important de ne pas installer d'autres “sip”, car PyQt4 est configuré avec une version précise de sip, et la bibliothèque correspondante, sip.so, devra accompagner votre programme “standalone”.

Installation de cx_freeze sur Ubuntu 10.10

cx_freeze est un paquet qui existe sous Ubuntu 10.10, et la première chose qu'on pense à faire est de l'installer. C'est en général une bonne pratique, mais pas ici: la version fournie, la 4.0.1, est insuffisante pour l'option dont on aura besoin: bin_path_includes, qui permettra d'intégrer des bibliothèques supplémentaires, et qui n'est apparu qu'avec la version 4.2.1. On va donc télécharger le code source et l'intégrer par compilation:

  • installer, à cause de la compilation, le paquet python-dev. A noter que le compilateur gcc est déjà préinstallé.
  • désarchiver ⇒ cela donne un répertoire cx_Freeze-4.2.2 dans lequel il y a tout. Vous le placez ou vous voulez dans votre /home.
  • faire venir une console, et se placer dans le répertoire cx_Freeze-4.2.2 (cd /home/..chemin../cx_Freeze-4.2.2)
  • le fichier README.txt dit clairement (et très succintement!) ce qu'il faut faire (j'ai ajouté le 'sudo' qui manquait):
python setup.py build
sudo python setup.py install

Il vient un grand nombre de messages: ne vous laissez pas impressionner: il suffit de vérifier qu'il n'y a pas d'erreur!

Voilà, vous avez le cx_freeze le plus récent!

Configuration du cx_freeze pour PyQt4

Il existe plusieurs façons d'utiliser cx_freeze, et j'ai choisi l'utilisation de setup.py (même méthode que pour py2exe sous Windows). L'avantage est que, si on débrouille bien, le même setup.py pourra être utilisé sous Windows et sous Linux.

J'utilise un “modèle” de setup.py que je fais évoluer au gré de mes programmes, et, il faut bien le dire, au gré de mes (nombreux et longs) tâtonnements.

Voilà les particularités des options de setup.py pour des programmes complexes PyQt4 avec QtSql (se reporter au code plus bas):

  • Si votre programme comporte des modules à intégrer, placés dans des sous-répertoires, il faut citer ces sous-répertoires dans l'option “path”.
  • il faut dire que la bibliothèque sip.so soit intégrée avec l'option “includes”: [“sip”]
  • les fichiers et répertoires à copier en plus (ex: les fichiers d'aide) sont mentionnés avec l'option “include_files”. Chaque copie demandée est un tuple composé du chemin source (absolu ou relatif) et du chemin destination (toujours relatif). Par exemple pour recopier un répertoire comportant les fichiers d'aide: “include_files”: [(“aide”, “aide”)]. Notez que les options comportent un blanc souligné et pas un tiret comme dit dans la notice de cx_freeze!
  • Et c'est le cas pour QtSql: dans la version “standalone”, les drivers SQL seront cherchés dans le sous-répertoire “sqldrivers” (j'ai mis une 1/2 journée à trouver cela…). Il faut donc demander la recopie des drivers avec l'option “include_files”: [(“/usr/lib/qt4/plugins/sqldrivers”,“sqldrivers”)].
  • Dans mes premiers essais, je me suis aperçu que toutes les bibliothèques nécessaires n'étaient pas installée. J'ai même passé 2 heures à les installer à la main au gré des messages d'erreurs en console: insupportable. On résout cela facilement avec l'option bin_path_includes: [“/usr/lib”]: toutes les bibliothèques nécessaires sont automatiquement intégrées avec ça! C'est cette option qui a justifié l'installation d'une version récente de cx_freeze.

Et c'est tout: avec ça, vous récupérez un répertoire avec tout ce qu'il faut pour une exécution “standalone” sur un Ubuntu “brut d'install”!

Voilà un exemple de code du setup.py que j'ai utilisé pour un logiciel de concours photos pour un photo-club (environ 10000 lignes de code et utilisation de QtSql).

Le code ci-dessous fonctionne sans modification sous Windows et sous Linux. Si on veut utiliser le même code pour Windows et Linux, il faut utiliser à plusieurs endroits les tests habituels de plateforme (if sys.platform == “win32” ou if sys.platform == “linux2”) puisque certaines adresses de bibliothèques sont différentes.


#!/usr/bin/python
# -*- coding: utf-8 -*-
# Python 2.7
# 02/2011
 
import sys, os
from cx_Freeze import setup, Executable
 
#############################################################################
# preparation des options 
 
# chemins de recherche des modules
path = sys.path + ["biblio", "consultations", "etatbase", "etiquettes", 
                   "jugement", "publications", "retourcolis", "saisiebord", 
                   "verifications", "vuetable"]
 
# options d'inclusion/exclusion des modules
includes = ["sip"]
excludes = []
packages = []
 
# copier les fichiers et/ou répertoires et leur contenu:
includefiles = [("aide", "aide")]
if sys.platform == "linux2":
    includefiles += [(r"/usr/lib/qt4/plugins/sqldrivers","sqldrivers")]
elif sys.platform == "win32":
    includefiles += [(r"C:\Python27\Lib\site-packages\PyQt4\plugins\sqldrivers","sqldrivers")]
else:
    pass
 
# pour inclusion éventuelle de bibliothèques supplémentaires
binpathincludes = []
if sys.platform == "linux2":
    # pour que les bibliothèques de /usr/lib soient copiées aussi
    binpathincludes += ["/usr/lib"]
 
# construction du dictionnaire des options
options = {"path": path,
           "includes": includes,
           "excludes": excludes,
           "packages": packages,
           "include_files": includefiles,
           "bin_path_includes": binpathincludes
           }
 
#############################################################################
# preparation des cibles
base = None
if sys.platform == "win32":
    base = "Win32GUI"
 
cible_1 = Executable(
    script = "concoursphotos.pyw",
    base = base,
    compress = True,
    icon = None,
    )
 
#############################################################################
# creation du setup
setup(
    name = "concoursphotos",
    version = "1",
    description = "Traitement de concours photos sous Windows et Linux",
    author = "Tyrtamos",
    options = {"build_exe": options},
    executables = [cible_1]
    )

Une fois le setup.py écrit et mis dans la racine du répertoire du programme à traiter (/chemin par exemple):

  • on fait venir une console, et on se place dans ce répertoire (cd /chemin)
  • on fait alors:
python setup.py build
  • Une longue liste de messages indique ce que cx_freeze fait. Il faut seulement vérifier qu'il n'y a pas d'erreur. Sinon, il faut modifier le setup.py jusqu'à ce que les erreurs aient disparu.
  • Dans le répertoire dans lequel on est (/chemin), il vient le sous-répertoire build/exe.linux-i686-2.6 dans lequel il y a la version “standalone” pouvant être diffusée. Vous pouvez, bien entendu, la proposer sous forme d'archive en un seul fichier.
  • Il ne reste plus qu'à l'essayer sur un Ubuntu “brut d'install”. On le copie donc, on met un droit d'exécution sur le fichier exécutable qu'on a défini dans le setup (il pourrait y en avoir plusieurs), et on peut le lancer. Dans un premier temps, il est conseillé de le lancer à partir d'une console pour avoir tous les éventuels messages d'erreur.
  • Si c'est ok, on peut alors le lancer directement avec une icône (à créer) du bureau, voire l'intégrer dans le menu des applications.


Amusez-vous bien!

cx_freeze_pyqt4_linux.txt · Dernière modification: 2011/02/22 04:42 de tyrtamos

Outils de la page