IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PyQt Python Discussion :

Traduction d'une fenetre secondaire


Sujet :

PyQt Python

  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut Traduction d'une fenetre secondaire
    Bonjour,

    toujours dans l'idée d'une amélioration de mon logiciel en cours de création.

    Je rencontre encore un soucis au niveau de la traduction, en effet j'ouvre une fenêtre secondaire de type About via le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class MKVExtractorGui(QMainWindow):
         self.ui.about_open.activated.connect(self.AboutMKVExtractorGui)
    ....
     
        def AboutMKVExtractorGui(self):
            """Affichage de la fenetre about."""
            dial = QDialog()
            self.about = Ui_about_window()
            self.about.setupUi(dial)
            reply = dial.exec_()
    Cela fonctionne très bien.
    Mais le soucis est celui de la traduction, en effet bien que le fichier de traduction contienne les textes de la fenêtre, impossible d'avoir la traduction.

    Comment peut-on faire pour avoir la traduction de la fenêtre ?

    Merci
    Sous Kubuntu 20.04

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je ne sais pas utiliser la traduction en général (QTranslator, etc...), mais comme je fais des programmes en français pour des français, j'ai tout de même trouvé comment traduire les boutons des messagebox pour avoir "oui/non" et pas "yes/no". Voir mon tuto:

    http://python.jpvweb.com/mesrecettes...t4_traductions
    http://pyqt.developpez.com/tutoriels...4/traductions/

    Pour la traduction en général, je suis intéressé, mais je n'ai pas encore trouvé un tuto assez simple pour me donner envie. Par contre, il y a un exemple fourni avec PyQt4 qui fonctionne bien. Sous Windows, il est ici: C:\Python27\Lib\site-packages\PyQt4\examples\tools\i18n.

    Si tu réussis, ce serait bien que tu expliques comment tu as fait!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    je regarde ça tout à l'heure.

    Sinon la traduction est très simple

    1) Utiliser la commande tr("la chaine à traduire") dans ton son script python.
    ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.widget.setStatusTip(tr("Bonjour je suis une chaine traduite"))
    Possibilité d'utiliser trUTF8 egalement si pas python3 d'utilisé.


    2) Permettre la traduction des textes des widgets via qtdesigner (option activée pour chaque texte de chaque widget par défaut) si qtdesigner est utilisé.


    3) Lancer une petite commande qui va lister tous les textes à traduire dans un fichier ts (translate) :
    ex avec mon logiciel MKVExtractorGui.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pylupdate4 MKVExtractorGui.ui MKVExtractorGui.py -ts MKVExtractorGui_fr_FR.ts
    pylupdate4 ou pylupdate5 en fonction de qt.
    MKVExtractorGui_fr_FR.ts : langue qui résultera (fr_FR si anglais => Francais ou en_EN si Francais => anglais).

    Le fichier ts est à conserver, car si la commande ci-dessus est à nouveau exécutée, le fichier sera simplement mis à jour. Sans lui il faudra tout recommencer depuis 0.

    Il y a également l'option -noobsolete qui peut être pratique, elle vire tous les anciens textes qui ne sont plus utilisés.
    Par défaut le fichier conserves tous les textes utilisés mais ne les envoie pas dans le fichier qm.


    4) Ouvrir le fichier ts via le logiciel qlinguist.


    5) Traduire via l'interface graphique les différents textes. (si qtdesigner est utilisé (où est-ce pyqt ?), on a même le droit à l'interface graphique traduite en temps réel )


    6) Une fois les traductions OK, il faut cocher la petite icone devant les textes du widget "Source texte" pour qu'il passe en tic vert (preuve que c'est validé).


    7) Il faut maintenant exporter le travail au format qm.
    Cela se fait simplement via "File" > "Release" du logiciel qlinguist.


    8) Quelques modifications dans le fichier python est ça sera bon
    J'ai ajouté ceci dans la classe de ma GUI, dans la fonction __init__ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # Pour une détection automatique de la langue locale
    locale = QLocale.system().name() # De type en_EN ou fr_FR
     
    # Et pour une version forcée :
    # locale = "fr_FR"
     
    appTranslator = QTranslator()
      # il est inutile d'indiquer l'extension du fichier
      if appTranslator.load("MKVExtractorGui_{}".format(locale)):
        app.installTranslator(appTranslator)
     
    ...
    self.show() # Affichage de la fenêtre principale
    et hop !
    Voila tout est bien traduit



    Pour utiliser une traduction dynamique (changement de langue sans redémarrer), la démarche ci-dessus est donc à faire plus ce qui suit.
    Ex en passant via une combobox qui propose fr ou en et dont le logiciel est en anglais de base et dont la GUI a été créée par qtdesigner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def OptionLanguage(self, value):
      """Fonction modifiant en temps réel la traduction."""
      # Partie la plus simple, celle qui retraduit le fichier py créé depuis qtdesigner qui propose une fonction de retraduction
      if value == "fr":
        locale = "fr_FR" # Mise à jour de la variable
        appTranslator = QTranslator()
        appTranslator.load("MKVExtractorGui_{}".format(locale))
        app.installTranslator(appTranslator)
        self.retranslateUi(self) # lance la fonction retranslateUi tres pratique
     
      else:
        locale = "en_EN"
        self.retranslateUi(self)
    Ça, c'est pour la partie fun de qtdesigner

    Pour toutes les traductions du fichier python, il faut relancer toutes les commandes ayant du texte déjà affiché.
    Les commandes suivantes seront bien traduites puisque le changement de langue à été fait...

    Ça, c'est la partie moins fun...

    Il faut, par exemple, relancer le texte actuellement affiché par la statusBar, le contenu des combobox faites à la main, des tree, table, list, lineEdit, textEdit...


    Pour information il est possible de traduire un dictionnaire simplement :
    ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    self.Traductions = {"MKVOpen" : self.tr("Select the MKV File"),
                               "MKVFolder" : self.tr("Select the output folder"),
                               "MKClean" : self.tr("Select the output MKV file")}
    Mais même le dictionnaire aura besoin d’être rechargé après coup...


    Il est donc plus simple (ou pas...) de regrouper, comme le fait qtdesigner, toutes les commandes envoyant des infos dans une fonction qui sera exécutée au démarrage et après chaque changement de langue (surtout dans le cas ou qtdesigner n'est pas utilisé pour les setStatusTip par ex).


    Voila, en espérant que ce soit compréhensible... si ça manque de précision, dites le moi
    Sous Kubuntu 20.04

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Merci pour tout ça! Je vais creuser.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Pas de soucis, pour une fois que je peux aider ici

    J'essaie de pousser la traduction le plus loin possible pour être à 100% FR/EN.

    Me reste que cette fichue fenêtre d'à propos :p

    EDIT : La fenêtre d'about qt est en EN aussi... mmhhh...
    Sous Kubuntu 20.04

  6. #6
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Quel est le type de ta fenêtre about?

    Au cas où, voilà ce que j'applique pour l'about de mes projets:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import sys
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    from sip import SIP_VERSION_STR
     
    #============================================================================
    __logiciel__ = u"logiciel"
    __version__ = u"1.0.0"
    __date__ = u"1/1/2013"
    __auteur__ = u"auteur"
     
    #============================================================================
    def apropos():
        """Fenêtre 'à propos' du logiciel"""
        pf = sys.platform
        if pf=='win32': pf='Windows'
        elif pf=='linux2': pf = 'Linux'
        elif pf=='sunos5': pf='Sun OS'
        else: pass
     
        QtGui.QMessageBox.about(None, u"A propos du logiciel",
        u"""%s version %s  (%s)
      Copyright %s
      Licence GPL3
      Source sur demande ici: http://accueil.jpvweb.com
     
    Contexte d'exécution en cours:
      Système d'exploitation: %s
      Python version: %s
      Sip version: %s
      PyQt4 version: %s
      Qt version: %s""" % (\
            __logiciel__, 
            __version__, 
            __date__, 
            __auteur__,
            pf,
            sys.version,
            SIP_VERSION_STR,
            QtCore.PYQT_VERSION_STR, 
            QtCore.QT_VERSION_STR )
            )
     
    #############################################################################
    def aproposqt():
        """Fenêtre 'à propos' de la bibliothèque graphique Qt """
        QtGui.qApp.aboutQt()
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
     
            self.bouton1 = QtGui.QPushButton(u"A propos", self)
            self.bouton1.clicked.connect(apropos)
            self.bouton2 = QtGui.QPushButton(u"A propos de Qt", self)
            self.bouton2.clicked.connect(aproposqt)
     
            posit = QtGui.QGridLayout()
            posit.addWidget(self.bouton1, 0, 0)
            posit.addWidget(self.bouton2, 1, 0)
            self.setLayout(posit)
     
        def apropos_m(self):
            pass
     
        def aproposqt_m(self):
            pass
     
    #############################################################################
    if __name__ == "__main__":
        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)
     
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    Et avec ça, la fenêtre "about Qt" est en français!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  7. #7
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Bien vu le coup du
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)
    c'est ce qu'il me manquait a priori

    je continue mes recherches et quand j'aurais tout traduit, je poste le retour !
    Sous Kubuntu 20.04

  8. #8
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    J'ai également trouvé comment traduire ma fameuse seconde fenêtre très simplement

    Je décris le système demain.

    Par contre il semble impossible de modifier le fichier de traduction qt à la volée.
    Une fois chargé plus possible d'en changer (j'ai tester update et repaint sur la fenêtre mais rien...) on verra si d'autres ont plus d'idées
    Sous Kubuntu 20.04

  9. #9
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Bon, voila donc la suite des explications

    1) La 1ere étape de séparer les fenêtres dans le corps du fichier python avec chaqu'un sa class.


    2) Chargement de l'interface graphique (venant du fichier ui) .


    3) Lancement de la traduction


    4) Affichage de la fenêtre


    Je vais essayé de poster un exemple simple...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    from PyQt4.QtGui import *
    from PyQt4.QtCore import *
     
    import sys
     
    from ui_window1 import Ui_Window1 # Fenetre principale
    from ui_window2 import Ui_Window2 # Fenetre secondaire
     
    locale = QLocale.system().name()
     
    #############################################################################
    class ui_window2(QMainWindow):
        def __init__(self, parent=None):
            # Récupération des widgets
            super(ui_window2, self).__init__(parent)
            self.Win2 = Ui_Window2()
            self.Win2.setupUi(self)
     
            # Création des connexions
            self.Win2.SuperButton.clicked.connect(self.SuperFonction)
     
            # Traduction du logiciel
            appTranslator = QTranslator()
            if appTranslator.load("Software_{}".format(locale):
                app.installTranslator(appTranslator)
     
            self.show() # Affichage de la fenetre
     
        def SuperFonction(self):
            print("Bonjour !")
     
     
    #############################################################################
    class ui_window1(QMainWindow):
        def __init__(self, parent=None):
            # Récupération des widgets
            super(ui_window1, self).__init__(parent)
            self.Win1 = Ui_Window1()
            self.Win1.setupUi(self)
     
            # Création des connexions
            self.Win1.SmallButton.clicked.connect(self.SmallFonction)
     
            # Traduction du logiciel
            appTranslator = QTranslator()
            if appTranslator.load("Software_{}".format(locale):
                app.installTranslator(appTranslator)
     
            self.show() # Affichage de la fenetre
     
        def SmallFonction(self):
            print("Ceci n'est qu'un petit salut...")
     
     
    #############################################################################
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ui_window1 = ui_window1()
     
       # Traduction de qt (pour qdialogQt, les bouton yes/no/cancel...)
        qtTranslator = QTranslator()
        if qtTranslator.load("qt_{}".format(locale), QLibraryInfo.location(QLibraryInfo.TranslationsPath)):
            app.installTranslator(qtTranslator)
     
        app.exec_()
    Donc normalement tout passe bien mais je n'arrive pas à changer la langue chargée par qt... même si on rafraîchit la fenêtre...

    Et surtout la traduction de qt doit être dans le if sinon la langue n'est pas modifiée par la suite...

    C'est étrange qu'on ne puisse en changer...


    J’espère que je n'ai pas fait d'erreur dans le code et que c'est clair


    PS : En séparant ainsi les fenetres, setCentralWidget(self.centralwidget) ne pose plus de soucis
    Sous Kubuntu 20.04

  10. #10
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je viens de passer plusieurs heures à me dépatouiller avec la traduction, et j'ai trouvé une solution qui a l'air de fonctionner. Mais nom d'un chien, quel bazar!. Les anglos-saxons ont vraiment des problèmes avec tout ce qui n'est pas de l'ASCII pur...

    Point de départ:
    - Python 2.7 et PyQt4
    - le code Python-PyQt4 est écrit et enregistré en utf-8.
    - Je considère que la langue de base est le français, et je veux permettre sur demande la traduction en anglais.
    - Cela concerne non seulement les différents textes, mais aussi les messages Qt (exemple: oui/non <=> yes/no).
    - Dans un 1er temps, la langue est choisie au lancement du programme (donc, pas de changement de langue en cours d'exécution).
    - Dans un 1er temps, je n'ai pas tenu compte d'un éventuel fichier issu de QtDesigner.

    Premières constatations: il y a une foule de solutions qu'on voit partout mais qui ne marchent pas chez moi. Par exemple pour le titre d'une fenêtre QWidget:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    self.setWindowTitle(self.tr("fenêtre")) => mauvais affichage fenêtre
     
    self.setWindowTitle(self.tr(u"fenêtre")) => mauvais affichage xml: "<source>fen&#xc3;&#xaa;tre</source>"
     
    self.setWindowTitle(self.trUtf8("fenêtre")) => erreur pylupdate4: "Non-ASCII character detected in trUtf8 string"
     
    self.setWindowTitle(self.trUtf8(u"fenêtre")) =>  erreur pylupdate4: "Non-ASCII character detected in trUtf8 string"
    J'ai essayé aussi des tas d'autres solutions, y compris celle utilisée par qtdesigner: il y a toujours quelque chose qui ne marche pas.

    Finalement, la seule solution qui a donné satisfaction est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.setWindowTitle(QtCore.QCoreApplication.translate("Fenetre", "fenêtre", None, QtGui.QApplication.UnicodeUTF8))
    A noter que c'est aussi la recommandation officielle de riverbank: http://pyqt.sourceforge.net/Docs/PyQ...n-pyqt4-and-qt

    Voilà donc mon code de test (test06.py):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import sys
     
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
     
            self.setWindowTitle(QtCore.QCoreApplication.translate("Fenetre", "fenêtre", None, QtGui.QApplication.UnicodeUTF8))
     
            self.resize(400, 300)
     
            self.bouton = QtGui.QPushButton(QtCore.QCoreApplication.translate("Fenetre", "bouton éèçàùôï€", None, QtGui.QApplication.UnicodeUTF8), self)
            self.bouton.clicked.connect(self.boutonclic)
     
            posit = QtGui.QGridLayout()
            posit.addWidget(self.bouton, 0, 0)
            self.setLayout(posit)
     
        def boutonclic(self):
            reponse = QtGui.QMessageBox.question(self, 
                u"Question",
                QtCore.QCoreApplication.translate("Fenetre", "Est-ce que la traduction marche?", None, QtGui.QApplication.UnicodeUTF8), 
                QtGui.QMessageBox.Yes, 
                QtGui.QMessageBox.No)
     
            if reponse == QtGui.QMessageBox.Yes:
                print u"Ok!"
            else:
                print u"Non!"
     
    #############################################################################
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
     
        # pour une détection automatique de la langue locale
        #locale = QtCore.QLocale.system().name() # => De type en_EN ou fr_FR
     
        # pour une version forcée :
        locale = "fr_FR"
        #locale = "en_EN"
     
        # traduction des textes
        translator1 = QtCore.QTranslator()
        if translator1.load(u"test06_" + locale):
            app.installTranslator(translator1)
     
        # traduction des messages Qt
        translator2 = QtCore.QTranslator ()
        if translator2.load(QtCore.QString("qt_") + locale, QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)):
            app.installTranslator(translator2)
     
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    Une fois ce code Python terminé, on fabrique le fichier test06_fr_FR.ts avec, en console:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pylupdate4 test06.py -ts test06_fr_FR.ts
    Ce qui donne le fichier "test06_fr_FR.ts" qui contient du XML:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE TS><TS version="2.0">
    <context>
        <name>Fenetre</name>
        <message encoding="UTF-8">
            <location filename="test06.py" line="20"/>
            <source>fenêtre</source>
            <translation type="unfinished"></translation>
        </message>
        <message encoding="UTF-8">
            <location filename="test06.py" line="24"/>
            <source>bouton éèçàùôï€</source>
            <translation type="unfinished"></translation>
        </message>
        <message>
            <location filename="test06.py" line="32"/>
            <source>Est-ce que la traduction marche?</source>
            <translation type="unfinished"></translation>
        </message>
    </context>
    </TS>
    On voit que la traduction d'un texte se réfère à un fichier précis et à un numéro de ligne. Il y a un avantage: le même texte peut avoir une traduction différente selon l'endroit dans le code. Mais il y a un inconvénient: toute modification, ne serait-ce que de numéro de ligne (ajout d'un commentaire par exemple) nécessitera de tout recommencer le processus de traduction...

    Curieusement, le seul exemple fourni avec PyQt4 et concernant ces problèmes de traduction (sous Windows: C:\Python27\Lib\site-packages\PyQt4\examples\tools\i18n) donne un fichier .ts qui fait une traduction de type dictionnaire français-anglais, sans référence à un nom de fichier ni à un numéro de ligne. Mais je ne sais pas comment le fabriquer. C'est bien dommage, parce que ça pourrait être suffisant pour les programmes simples.

    On a le fichier "test06_fr_FR.ts", on va maintenant fabriquer 2 fichiers pour les traductions:
    - "test06_fr_FR.qm" pour la "traduction" français=> français,
    - et "test06_en_EN.qm" pour la traduction français=>anglais.
    On va faire ça avec "linguist" qui est un logiciel graphique.

    On lance linguist.

    On ouvre le fichier "test06_fr_FR.ts". Il vient une petite fenêtre qui demande la langue source (français ici) et la langue destination (français aussi dans un 1er temps). Ce fichier s'affiche en 3 colonnes:
    - à gauche le nom de la classe (ici: "Fenetre")
    - au milieu tous les textes en français à traduire
    - à droite le code complet Python pour repérage du contexte des textes à traduire

    Mais problème: si les textes à traduire situés au milieu sont bien affichés, le code complet à droite n'est pas affiché en utf-8 mais en latin1: les affichages des textes contenant des caractères accentués sont donc moches: "bouton éèçàùôï€" s'affiche "bouton éèçà ùôï€". Je n'ai pas trouvé comment changer ça, mais ça n'empêche pas le logiciel de fonctionner.

    Il faut donc écrire les traductions. On sélectionne un par un les textes à traduire, on met la traduction dans la case (du français au français, c'est un copier/coller), et on clique sur le "?" devant chaque texte pour valider chaque traduction. En fait, puisque c'est du français au français, il est acceptable de ne rien mettre dans la traduction.

    Quand la traduction est terminée (il n'y a plus de "?"), on fait "Release As", et on donne le nom "test06_fr_FR.qm": le fichier de traduction du français au français est fabriqué.

    Maintenant, on appelle au menu l'item edit => translation file setting. Cela remet la petite fenêtre qui demande le langage source (toujours ici le français) et le langage destination (cette fois-ci, c'est l'anglais).

    On reprend la méthode précédente, mais cette fois-ci, on donne les traductions en anglais des textes à traduire. Ici:
    "fenêtre" => "window"
    "bouton éèçàùôï€" => "button"
    "Est-ce que la traduction marche?" => "Does the translation work?"

    Après validation des textes (il ne doit plus y avoir de "?" devant), on fait "Release As" et on donne cette fois le nom "test06_en_EN.qm".

    On a fini!

    On voit dans le code qu'au lancement du programme:

    - on initialise la locale, soit en demandant le langage courant de l'OS, soit en forçant par: locale="fr_FR" ou locale="en_EN".

    - et on installe les 2 fichiers de langue .qm:
    ==> le fichier test06_+locale (qui donnera "test06_fr_FR.qm" ou "test06_en_EN.qm" selon la locale choisie)
    ==> ainsi que le fichier "qt_"+locale (qui donnera "qt_fr_FR.qm" ou "qt_en_EN.qm" selon la locale choisie), mais il faudra dire à quel endroit il se trouve: QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath).

    Et ça marche:
    - locale="fr_FR" donnera bien tous les textes en français, y compris le "oui/non" du messagebox,
    - et locale="en_EN" donnera tous les textes en anglais, y compris le "yes/no" du messagebox.

    Ouf... Mais quand je pense qu'à chaque changement du code il faudra tout recommencer

    A moins qu'il y ait des simplifications qui m'avaient échappé? Toute idée dans ce sens est la bienvenue!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  11. #11
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Petit complément à mon message précédent.

    Quand la fenêtre est dessinée par qtdesigner, c'est pareil: il suffit d'ajouter le fichier.ui dans les arguments de pylupdate4. Par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pylupdate4 test_ui.ui test.py -ts test_fr_FR.ts
    Tout le reste est identique

    On remarque qu'on n'utilise pas le fichier "test_ui.py" résultat de la conversion de .ui par pyuic4!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  12. #12
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    Billets dans le blog
    15
    Par défaut


    Je passe en coup de vent et du coup n'ai pas lu l'intégralité de vos message. Mais je suis surpris que vous ayez tant de problèmes.

    Il y a quelques temps, j'ai eu à vouloir moi aussi traduire les boutons des diverses boites de dialogue et voici comme je mis suis pris. De mémoire je n'ai pas rencontré tous ces problèmes. Alors j'ai eu du gros bol, soit je n'ai pas poussé la réflexion aussi loin .

    Voici la note que j'avais prévu d'ajouter à la FAQ à l'époque mais que je n'ai jamais eu le temps de concrétiser (si dourouc passe par là, je suis mal moi... ça date de novembre 2011 ) :

    PyQt et PySide permettent de traduire facilement les textes de boutons des boîtes de dialogue initialement en anglais.
    Pour cela, il est nécessaire de récupérer dans un premier temps le fichier correspondant à la langue voulue.
    Par exemple, sous windows et pour PyQt pour Python 3, vous devriez trouver ceci dans : C:\Python32\Lib\site-packages\PyQt4\translations

    Pour la langue française, on choisira le fichier qt_fr.qm.

    Il faudra ensuite déclarer ceci dans la partie de notre code initialisant notre programme.
    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # -*- coding:utf-8
     
    from PyQt4.QtGui import QMainWindow, QApplication
    from PyQt4.QtCore import QTranslator
    import sys
     
    class MainWindow(QMainWindow):
        def __init__(self, parent = None):
            QMainWindow.__init__(self, parent)
     
            #widget = QWidget(self)
     
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        main = MainWindow()
        translator = QTranslator()
        translator.load("qt_fr.qm")
        app.installTranslator(translator)
        main.show()
        sys.exit(app.exec_())
    J'espère que ça pourra t'aider.
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  13. #13
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Rebonjour Jiyuu,

    Merci de ta réponse, mais ce point concernant qt_fr.qm ne pose pas de problème et fonctionne bien. J'avais même édité une évolution de ce code pour qu'il continue à fonctionner après traitement par cx_freeze.

    Ce qui fait l'objet de mon message ci-dessus, c'est toutes les autres traductions qu'on doit faire: titre de fenêtre, label, bouton, etc...

    Pour l'instant, ça marche en statique (choix de la langue au lancement), y compris avec des fenêtres dessinées par qtdesigner.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  14. #14
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Premières constatations: il y a une foule de solutions qu'on voit partout mais qui ne marchent pas chez moi. Par exemple pour le titre d'une fenêtre QWidget:
    Alors ca ne venait pas de chez moi
    Perso je fais ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    # Creation d'un dictionnaire contenant tous les textes :
    Traductions = {"MKVOpen" : self.tr("Select the MKV File"),
                  "MKVDirNameOut" : self.tr("Select the output folder"),
                  "MKClean" : self.tr("Select the output MKV file"),
                  "Log" : self.tr("Error : No Log file found"),}
     
    # Titre de fenetre
    QFileDialog.getExistingDirectory(self, Traductions["MKVDirNameOut"])
    Et la le texte s'affiche sans soucis.


    Mais problème: si les textes à traduire situés au milieu sont bien affichés, le code complet à droite n'est pas affiché en utf-8 mais en latin1: les affichages des textes contenant des caractères accentués sont donc moches: "bouton éèçàùôï€" s'affiche "bouton éèçà ùôï€". Je n'ai pas trouvé comment changer ça, mais ça n'empêche pas le logiciel de fonctionner.
    J'ai également rencontré le même soucis, d'où l’intérêt d’écrire son logiciel en EN directement et de ne créer qu'un fichier de traduction FR.


    On voit que la traduction d'un texte se réfère à un fichier précis et à un numéro de ligne. Il y a un avantage: le même texte peut avoir une traduction différente selon l'endroit dans le code. Mais il y a un inconvénient: toute modification, ne serait-ce que de numéro de ligne (ajout d'un commentaire par exemple) nécessitera de tout recommencer le processus de traduction...
    Heuuu.... pas tout pigé.
    Quel est le problème ? Même si tu modifies ton fichier python mais que tu ne modifies pas les textes, le fichier qm fonctionne très bien.
    Pour le fichier ts, il suffit juste de le mettre à jour en relançant la traduction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pylupdate4 test06.py -ts test06_fr_FR.ts
    Attention, il faut conserver le fichier ts traduit, ainsi inutile de tout recommencer lors du prochain lancement de la commande ci-dessus.


    Sinon je suis toujours bloquer dans ma tentative de changement dynamique de la langue pour les yes/no des widgets.
    Impossible de changer la langue du fichier qt en cours ?
    Aucun soucis pour tous les textes perso mais pour le qt...



    Pour info lors du lancement de la commande setLanguage(), cela créé un evement languageChange que l'on peut récupérer pour lancer la traduction ou autre...
    Sous Kubuntu 20.04

  15. #15
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Merci de ta réponse. Je te fais déjà une 1ère réponse pour le problème suivant:

    Citation Envoyé par hizoka Voir le message
    Sinon je suis toujours bloquer dans ma tentative de changement dynamique de la langue pour les yes/no des widgets.
    Impossible de changer la langue du fichier qt en cours ?
    Si, c'est possible! Voilà un petit code tout simple qui simule la sélection de la locale par radiobouton, et qui montre la traduction des messages qt "oui/non" <=> "yes/no":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import sys
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    def changelangue(locale):
     
        global app, translator_qt
     
        # traduction des messages Qt
        translator_qt = QtCore.QTranslator()
        if translator_qt.load(QtCore.QString("qt_") + locale, QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)):
            app.installTranslator(translator_qt)
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        #========================================================================
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
     
            self.setWindowTitle(u"fenêtre")
            self.resize(400, 300)
     
            # création des boutons radio
            self.langue1 = QtGui.QRadioButton(u"français", self)
            self.langue1.clicked.connect(self.changelangue)
     
            self.langue2 = QtGui.QRadioButton(u"anglais", self)        
            self.langue2.clicked.connect(self.changelangue)
     
            # initialisation de la langue au lancement
            self.langue1.setChecked(True)
            self.changelangue()
     
            # creation du bouton pour voir le messagebox
            self.bouton = QtGui.QPushButton(u"bouton éèçàùôï€", self)
            self.bouton.clicked.connect(self.boutonclic)
     
            # positionnement dans la fenêtre
            posit = QtGui.QGridLayout()
            posit.addWidget(self.langue1, 0, 0)
            posit.addWidget(self.langue2, 1, 0)
            posit.addWidget(self.bouton, 2, 0)
            self.setLayout(posit)
     
        #========================================================================
        def changelangue(self):
            if self.langue1.isChecked():
                # passer au français
                changelangue("fr_FR")
            else:
                # passer à l'anglais
                changelangue("en_EN")
     
        #========================================================================
        def boutonclic(self):
            reponse = QtGui.QMessageBox.question(self, 
                u"Question",
                u"Est-ce que la traduction marche?",
                QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
            if reponse == QtGui.QMessageBox.Yes:
                print u"Ok!"
            else:
                print u"Non!"
     
    #############################################################################
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    Curieusement, ça me semblait naturel de déclarer dans la fonction changelangue que "app" était une variable globale, mais ça a marché seulement quand j'ai aussi déclaré translator_qt comme globale. D'où la ligne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        global app, translator_qt
    A noter que l'on peut installer plusieurs fichiers qm comme ça, et que dans l'exécution des instructions de traduction, la recherche se fait dans l'ordre inverse des installations (le plus récent d'abord = pile LIFO). Si nécessaire, on pourrait supprimer l'installation précédente avec "app.removeTranslator(...)" pour ne pas que la file augmente.

    Le reste suit.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  16. #16
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    La suite:

    Citation Envoyé par hizoka Voir le message
    Alors ca ne venait pas de chez moi
    Perso je fais ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    # Creation d'un dictionnaire contenant tous les textes :
    Traductions = {"MKVOpen" : self.tr("Select the MKV File"),
                  "MKVDirNameOut" : self.tr("Select the output folder"),
                  "MKClean" : self.tr("Select the output MKV file"),
                  "Log" : self.tr("Error : No Log file found"),}
     
    # Titre de fenetre
    QFileDialog.getExistingDirectory(self, Traductions["MKVDirNameOut"])
    Et la le texte s'affiche sans soucis.
    Bah oui, parce que tu travailles comme les anglo-saxons, en considérant que ton programme est D'ABORD écrit en anglais: sans les caractères accentués, tu n'as pas de problème d'encodage.

    Mais mes programmes à moi sont d'abord écrits en français, d'où les problèmes cités.

    Citation Envoyé par hizoka Voir le message
    J'ai également rencontré le même soucis, d'où l’intérêt d’écrire son logiciel en EN directement et de ne créer qu'un fichier de traduction FR.
    Tu as probablement raison, mais c'est loin, très loin, d'être naturel pour moi.

    Citation Envoyé par hizoka Voir le message
    Heuuu.... pas tout pigé.
    Quel est le problème ? Même si tu modifies ton fichier python mais que tu ne modifies pas les textes, le fichier qm fonctionne très bien.
    Pour le fichier ts, il suffit juste de le mettre à jour en relançant la traduction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pylupdate4 test06.py -ts test06_fr_FR.ts
    Attention, il faut conserver le fichier ts traduit, ainsi inutile de tout recommencer lors du prochain lancement de la commande ci-dessus.
    J'ai refais la manip. Mon soucis était que le numéro de ligne était cité dans le fichier .ts comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        <message>
            <location filename="test06.py" line="31"/>
            <source>Est-ce que la traduction marche?</source>
            <translation>Does the translation work?</translation>
        </message>
    Et donc, je pensais que chaque modif entrainant un changement de ce numéro de ligne nécessitait le renouvellement complet du processus de traduction. Ce n'est pas le cas, heureusement: un simple changement de numéro de ligne ne perturbe pas la traduction. Peut-être que si le numéro de ligne dans le fichier .ts est nécessaire pour construire le fichier .qm, celui-ci ne s'en sert plus après?

    De plus, si dans le programme linguist on a pris la précaution de mettre à jour la traduction test06_en_EN.ts après l'introduction de toutes les traductions, l'exécution ultérieure de pylupdate4 met à jour le fichier existant, sans perdre les traductions (je pensais qu'il refaisait le fichier à partir de zéro en perdant les traductions déjà introduites).

    Donc, ce n'est pas aussi grave que le pensais. Il reste que pour un gros programme (imaginons 200 mots à traduire en plusieurs langues), ça reste un sacré boulot.

    J'avais fait aussi comme remarque que le fichier .ts donné par PyQt4 à titre d'exemple ne référençait pas le numéro de ligne et s'apparentait plutôt à un dictionnaire français-anglais. Exemple issu du fichier C:\Python27\Lib\site-packages\PyQt4\examples\tools\i18n\translations\i18n_fr.ts pour une traduction anglais=> français:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        <message>
            <source>Second</source>
            <translation>Deuxième</translation>
        </message>
    Mais je ne sais pas fabriquer un tel fichier, et c'est bien dommage: un simple dictionnaire aurait pu suffire pour les programmes simples, parce que de nombreux mots sont communs (fichier<=>file, outils<=>tools, etc...).


    En tout cas, merci pour tes réponses. A part pour le changement de langue en dynamique (je vais mieux regarder ce que tu fais), mon "exploration" du sujet est presque arrivée à son terme pour l'instant.

    [edit] le dictionnaire simple français-anglais (ou le contraire) existe: ça s'appelle "phrasebooks" et ça prend une extension ".qph". Extrait de french.qph livré avec QtSQK v4.8:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <!DOCTYPE QPH>
    <QPH language="fr">
    <phrase>
        <source>About</source>
        <target>A propos</target>
    </phrase>
    ...
    <phrase>
        <source>active window</source>
        <target>fenêtre activ</target>
    </phrase>
    ...
    <phrase>
        <source>Run:</source>
        <target>Exécution :</target>
    </phrase>
    </QPH>
    Ce fichier est intégré sur demande dans la traduction par QLinguist. Mais je ne sais encore bien la place qu'il prend par rapport aux traductions normales.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  17. #17
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Cool ca fonctionne nickel ça

    C'est cool, on a bien poussé le truc !

    Reste plus qu'a voir ton dico qph.

    Perso je n'ai plus rien de non traduit !

    J'ai lu un truc y a pas longtemps, un mec disait que le 1er langage à apprendre était l'anglais...
    C'est pas con... mais heureusement que c'est pas obligatoire au vu de mon niveau !!! :p
    Sous Kubuntu 20.04

  18. #18
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Avant de regarder les fichiers qph, je viens de terminer un changement dynamique de langue français<=>anglais, et j'aimerais bien que tu me dises si tu as mieux. Dans le code test (Python 2.7, PyQt4), tout est traduit quand on passe d'un radiobouton à l'autre.

    test01.py:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import sys
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    def changelangage(fen, langage):
        """appelé à chaque changement de langage"""
     
        global app, translator_qt
     
        # traduction des messages Qt
        translator_qt = QtCore.QTranslator()
        if translator_qt.load(QtCore.QString("qt_") + langage, QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)):
            app.installTranslator(translator_qt)
     
        # installation de la traduction des textes
        translator = QtCore.QTranslator()
        if translator.load(u"test01_" + langage):
            app.installTranslator(translator)
     
        # forcer la traduction à chaque changement dynamique de langage
        fen.setWindowTitle(QtCore.QCoreApplication.translate("Fenetre", "fenêtre", None, QtGui.QApplication.UnicodeUTF8))
        fen.langue1.setText(QtCore.QCoreApplication.translate("Fenetre", "français", None, QtGui.QApplication.UnicodeUTF8))
        fen.langue2.setText(QtCore.QCoreApplication.translate("Fenetre", "anglais", None, QtGui.QApplication.UnicodeUTF8))
        fen.bouton.setText(QtCore.QCoreApplication.translate("Fenetre", "bouton éèçàùôï", None, QtGui.QApplication.UnicodeUTF8))
        fen.titrequestion = QtCore.QCoreApplication.translate("Fenetre", "Question", None, QtGui.QApplication.UnicodeUTF8)
        fen.question = QtCore.QCoreApplication.translate("Fenetre", "Est-ce que la traduction marche?", None, QtGui.QApplication.UnicodeUTF8)
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        #========================================================================
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
     
            self.setWindowTitle(QtCore.QCoreApplication.translate("Fenetre", "fenêtre", None, QtGui.QApplication.UnicodeUTF8))
            self.resize(400, 300)
     
            # création des boutons radio
            self.langue1 = QtGui.QRadioButton(QtCore.QCoreApplication.translate("Fenetre", "français", None, QtGui.QApplication.UnicodeUTF8), self)
            self.langue1.clicked.connect(self.changelangue)
     
            self.langue2 = QtGui.QRadioButton(QtCore.QCoreApplication.translate("Fenetre", "anglais", None, QtGui.QApplication.UnicodeUTF8), self)        
            self.langue2.clicked.connect(self.changelangue)
     
            # creation du bouton pour voir le messagebox
            self.bouton = QtGui.QPushButton(QtCore.QCoreApplication.translate("Fenetre", "bouton éèçàùôï", None, QtGui.QApplication.UnicodeUTF8), self)
            self.bouton.clicked.connect(self.boutonclic)
     
            # positionnement dans la fenêtre
            posit = QtGui.QGridLayout()
            posit.addWidget(self.langue1, 0, 0)
            posit.addWidget(self.langue2, 1, 0)
            posit.addWidget(self.bouton, 2, 0)
            self.setLayout(posit)
     
            # diverses initialisations pour préparer les changements de langue
            self.titrequestion = QtCore.QCoreApplication.translate("Fenetre", "Question", None, QtGui.QApplication.UnicodeUTF8)
            self.question = QtCore.QCoreApplication.translate("Fenetre", "Est-ce que la traduction marche?", None, QtGui.QApplication.UnicodeUTF8)
     
            # initialisation de la langue au lancement
            self.langue1.setChecked(True)
            self.changelangue()
     
        #========================================================================
        @QtCore.pyqtSlot()
        def changelangue(self):
            """appelé à chaque clic sur l'un des radioboutons de changement des 
               langues
            """
            if self.langue1.isChecked():
                # passer au français
                changelangage(self, "fr_FR")
            else:
                # passer à l'anglais
                changelangage(self, "en_EN")
     
        #========================================================================
        @QtCore.pyqtSlot()
        def boutonclic(self):
            """appelé au clic sur le bouton pour vérifier la traduction des 
               messages Qt
            """
            reponse = QtGui.QMessageBox.question(self, 
                self.titrequestion,
                self.question,
                QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
            if reponse == QtGui.QMessageBox.Yes:
                pass
            else:
                pass
     
    #############################################################################
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    Pour le faire tourner avec les traductions, j'ai tout mis dans un zip en pièce jointe.

    Pour faciliter les mises à jour, j'ai fait un fichier projet "test01.pro" qui contient en même temps les fichiers sources .py ou .pyw (SOURCES = ), les fichiers issus de qtdesigner .ui (FORMS = ), et les fichiers ts (TRANSLATIONS = ). Il pourait y avoir aussi des fichiers ressources (RESOURCES = ).

    test01.pro:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SOURCES = test01.py
    TRANSLATIONS = test01_fr_FR.ts \
                   test01_en_EN.ts
    Après ça, j'ai fait 2 scripts pour la console:

    test01_ts.bat qui lance la mise à jour des fichiers ts:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pylupdate4 -verbose test01.pro
    pause
    test01_qm.bat qui lance la mise à jour des fichiers qm:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lrelease test01.pro
    pause
    Avec ça, au fur et à mesure des modifs, tant que les textes à traduire ne nécessitent pas de lancer linguist, les mises à jour sont quasi immédiates.
    Fichiers attachés Fichiers attachés
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  19. #19
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    On fait la même chose à la différence qu'à la place d'utiliser de longues commandes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QtCore.QCoreApplication.translate("Fenetre", "bouton éèçàùôï", None, QtGui.QApplication.UnicodeUTF8)
    j'utilise simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.tr("bouton éèçàùôï")
    qui fonctionne pour tout sauf le titre de fenêtre.
    Et j'ai lu que tr() fonctionnait dans 98-99% des cas.

    Et dans le cas de titres de fenêtres je passe par une variable.
    Sous Kubuntu 20.04

  20. #20
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Chez moi, il faut que j'utilise self.trUtf8, sinon j'ai un affichage moche sur le bouton. Mais self.tr() et self.trUtf8 posent un problème embêtant avec les héritages. C'est dû aux différences entre Qt et PyQt dans la recherche du contexte (c'est dans la doc de PyQt4).

    Voilà un code qui le montre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import sys
    from PyQt4 import QtCore, QtGui
     
    app = QtCore.QCoreApplication(sys.argv)
     
    def changelangue(langue):
        global app, translator
        translator = QtCore.QTranslator()
        if translator.load(u"test01_" + langue):
            app.installTranslator(translator)
     
    class A(QtCore.QObject):
     
        def hello1(self):
            return QtCore.QCoreApplication.translate("A", "Bonjour", None, QtGui.QApplication.UnicodeUTF8)
     
        def hello2(self):
            return self.tr("Bonjour")
     
    class B(A):
        pass
     
    a = A()
    b = B()
     
    changelangue("fr_FR")
    print a.hello1()
    print b.hello1()
     
    changelangue("en_EN")
    print a.hello1()
    print b.hello1()
    print
     
    changelangue("fr_FR")
    print a.hello2()
    print b.hello2()
     
    changelangue("en_EN")
    print a.hello2()
    print b.hello2()
    Résultat:

    La 1ère solution avec QtCore.QCoreApplication.translate(...) donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Bonjour
    Bonjour
    Hello
    Hello
    Là, ça marche: la traduction est transmise par l'héritage.

    La 2e solution avec self.tr(...) donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Bonjour
    Bonjour
    Hello
    Bonjour
    Et là, ça ne va plus: la traduction n'est pas transmise par l'héritage, ce n'est pas normal!

    Et c'est bien dommage, parce que je préfèrerais écrire self.tr que ces lignes interminables!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. attendre la fermeture d'une fenetre secondaire
    Par hizoka dans le forum PyQt
    Réponses: 5
    Dernier message: 02/12/2013, 20h38
  2. ouvrir une fenetre secondaire depuis 1 bouton
    Par TheBlackReverand dans le forum MFC
    Réponses: 7
    Dernier message: 16/03/2006, 22h02
  3. [VB6] [Système] Récupérer le contenu d'une fenêtre DOS
    Par Nounours666 dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 18/11/2004, 16h38
  4. Aide sur une fenetre
    Par Ray-j dans le forum Autres éditeurs
    Réponses: 4
    Dernier message: 29/11/2002, 08h51
  5. gérer les jpg dans une fenetre directdraw???
    Par Anonymous dans le forum DirectX
    Réponses: 1
    Dernier message: 14/06/2002, 13h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo