I. Solution pour l'interpréteur "normal"

La solution est la suivante : il faut dire à PyQt4 qu'il doit traduire, mais il faut aussi lui dire où il doit trouver les fichiers de traduction selon la locale du PC.

Voilà le code à insérer, ce qui donnera pour le code de démarrage standard :

 
Sélectionnez
from PyQt4 import QtCore, QtGui
# ...
# ...ici la classe Fenetre
# ...
if __name__ == "__main__":
 
    # lancement de l'application 
    app = QtGui.QApplication(sys.argv)
 
    #========================================================================
    # pour assurer la traduction automatique du conversationnel à la locale
    locale = QtCore.QLocale.system().name()
    translator = QtCore.QTranslator ()
    translator.load(QtCore.QString("qt_") + locale,   
                  QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath))
    app.installTranslator(translator)
 
    #========================================================================
    # lancement de la fenetre
    fen = Fenetre()
    fen.show()
    sys.exit(app.exec_())

II. Solution pour un exécutable cx_Freeze (ou équivalent)

Vous avez fait ce qui précède, et vous essayez de faire une version autonome de votre programme grâce à cx_Freeze, transportée dans un Windows ou Linux sans PyQt4. Et là, ça ne marche plus !

Pourquoi ? Parce que l'exécutable ne trouve plus les fichiers de traduction de la locale. Et s'il ne les trouve pas, c'est qu'il les cherche au mauvais endroit.

L'exécutable après cx_Freeze cherche les fichiers de traduction :

  • sous Windows, ici: C:\Qt\4.7.1\translations (bizarre, parce qu'avec l'interpréteur, c'est: C:\Python27\Lib\Site-packages\PyQt4\translations) ;
  • sous Linux (Ubuntu 10.10), ici: /usr/share/qt4/translations.

La solution est dès lors évidente :

  • pendant le traitement par cx_Freeze, il faut copier le contenu du répertoire cherché dans un sous-répertoire “translations”. Cela peut se faire automatiquement en utilisant l'option “include_files” ;
  • il faut tester si on est avec l'interpréteur normal ou avec un exécutable fabriqué avec cx_Freeze. On peut faire ça en testant si le programme qu'on vient de lancer a une extension '.py' ou '.pyw' ;
  • il ne reste plus qu'à donner le bon chemin des fichiers de traduction à “translator.load”

Voilà le code que ça donne.

Pour le setup.py de cx_Freeze (tenir compte des éventuelles autres copies à faire par l'option “include_files”) :

 
Sélectionnez
if sys.platform == "linux2":
    options["include_files"] = [("/usr/share/qt4/translations","translations")]
elif sys.platform == "win32":
    options["include_files"] = [(r"C:\Python27\Lib\site-packages\PyQt4\translations","translations")]
else:
    # mettre ici la solution pour les autres OS
    pass

Et pour le code de démarrage de l'application :

 
Sélectionnez
from PyQt4 import QtCore, QtGui
# ...
# ...ici la classe Fenetre
# ...
if __name__ == "__main__":
 
    # lancement de l'application 
    app = QtGui.QApplication(sys.argv)
 
    #========================================================================
    # pour assurer la traduction automatique du conversationnel à la locale
    locale = QtCore.QLocale.system().name()
    translator = QtCore.QTranslator ()
    if os.path.splitext(sys.argv[0])[1] in ['.py', '.pyw']:
        # exécution par l'interpréteur normal
        reptrad = unicode(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath))
    else:
        # exécution de la version exécutable après cx_Freeze (ou équivalent): 
        #les fichiers de traduction doivent se trouver dans "translations"
        reptrad = unicode("translations")
    translator.load(QtCore.QString("qt_") + locale, reptrad)
    app.installTranslator(translator)
 
    #========================================================================
    # lancement de la fenetre
    fen = Fenetre()
    fen.show()
    sys.exit(app.exec_())

Et là, ça marche dans tous les cas.

Pour la version Windows traitée par cx_Freeze, ça continue à fonctionner avec le programme d'installation InnoSetup (qui va vraiment très bien avec cx_Freeze !).

À noter que je ne me suis pas contenté de la traduction en français : c'est la “locale” du PC qui sera utilisée !

III. Remerciements

Merci à dourouc05 et à ClaudeLELOUP pour leur relecture !