Sur cette page

Écrire le code source pour la traduction

Écrire le code source de QML et de Qt C++ de manière à pouvoir localiser les applications :

Lors du développement d'applications C++, voir également Considérations supplémentaires pour le code C++.

Marquer les chaînes de caractères pour la traduction

La plupart des textes qui doivent être traduits dans une application sont constitués de mots simples ou de phrases courtes. Ils apparaissent généralement sous forme de titres de fenêtres, d'éléments de menu, d'infobulles et d'étiquettes de boutons, de cases à cocher et de boutons radio.

Qt minimise le coût de performance de l'utilisation des traductions en traduisant les phrases pour chaque fenêtre au fur et à mesure qu'elles sont créées. Dans la plupart des applications, la fenêtre principale n'est créée qu'une seule fois. Les boîtes de dialogue sont souvent créées une seule fois, puis affichées et masquées selon les besoins. Une fois la traduction initiale effectuée, il n'y a plus de surcharge d'exécution pour les fenêtres traduites. Seules les fenêtres qui sont créées, détruites et créées par la suite auront un coût de performance de traduction.

Vous pouvez créer des applications qui changent de langue au moment de l'exécution, mais cela demande un effort et a un coût en termes de performances d'exécution.

Utilisez les fonctions de traduction pour marquer le texte de l'interface utilisateur visible par l'utilisateur en vue de sa traduction dans le code QML et C++. Qt prend en charge deux approches pour identifier le texte traduisible : basée sur le texte et basée sur l'ID.

Dans l'approche de traduction basée sur le texte, Qt indexe chaque chaîne traduisible par le contexte de traduction et éventuellement par un commentaire désambiguïsant auquel elle est associée. La même phrase peut apparaître dans plus d'un contexte sans conflit. Si une phrase apparaît plus d'une fois dans un contexte particulier, elle n'est traduite qu'une seule fois et la traduction est appliquée à chaque occurrence dans le contexte.

Dans l'approche de la traduction basée sur les identifiants, chaque traduction est identifiée de manière unique par un identifiant explicite. Les identifiants sont uniques pour l'ensemble du projet. Si un ID apparaît plusieurs fois dans un projet, il n'est traduit qu'une seule fois et la traduction est appliquée à chaque occurrence dans le projet.

QML

En QML, vous pouvez utiliser les fonctions suivantes pour marquer les chaînes visibles par l'utilisateur en vue de leur traduction dans les fichiers .qml :

  • qsTr() : Traduction basée sur le texte
  • qsTranslate() : Traduction basée sur le texte
  • qsTrId() : Traduction basée sur l'ID

qsTr() en mode texte :

Text {
    id: txt1
    text: qsTr("Back")
}

Ce code fait de Back une entrée clé dans les fichiers source de traduction (TS). Au moment de l'exécution, le système de traduction recherche le mot clé Back dans le contexte actuel (voir ci-dessous) et obtient ensuite la valeur de traduction correspondante pour la locale actuelle du système. Le résultat est renvoyé à la propriété text et l'interface utilisateur affiche la traduction appropriée de Back pour la locale actuelle. Si aucune traduction n'est trouvée, qsTr() renvoie la chaîne originale.

Le contexte de traduction peut être défini pour un fichier donné avec :

pragma Translator: ChosenContext

ou

pragma Translator: "Chosen::Context"

Le contexte défini via qsTranslate() a la priorité sur le contexte défini via pragma Translator . En QML, le contexte de traduction est par défaut le nom du fichier.

qsTrId() basé sur l'ID :

Text {
    id: txt1
    //% "Back"
    text: qsTrId("BackID")
}

Ce code fait de "BackID" une entrée clé unique dans les fichiers source de traduction (TS) et écrit "Back" comme texte source. Au moment de l'exécution, le système de traduction recherche l'ID "BackID" et obtient ensuite la valeur de traduction correspondante (ou, si elle n'est pas traduite, le texte source) pour la locale actuelle du système. Le résultat est renvoyé à la propriété text et l'interface utilisateur affiche la traduction appropriée de "BackID" pour la locale actuelle. Si aucune entrée avec l'ID "BackID" n'est trouvée dans les fichiers TS, qsTrId() renvoie l'ID lui-même. Cela ne devrait pas se produire dans des conditions normales.

C++

En C++, vous pouvez utiliser les fonctions suivantes pour marquer les chaînes de caractères visibles par l'utilisateur en vue de leur traduction :

Traduction basée sur le texte ()

Utilisez la fonction tr() pour marquer un texte comme traduisible et pour afficher le texte traduit. Le contexte de traduction est le nom de la sous-classe QObject dans laquelle la chaîne est utilisée. Pour définir le contexte de traduction des nouvelles classes basées sur QObject, utilisez la macro Q_OBJECT dans chaque nouvelle définition de classe.

Lorsque tr() est appelé, il recherche la chaîne traduisible à l'aide d'un objet QTranslator, que vous devez installer sur l'objet d'application, comme décrit dans Activer la traduction.

Par exemple, en supposant que LoginWidget est une sous-classe de QWidget:

LoginWidget::LoginWidget()
{
    QLabel *label = new QLabel(tr("Password:"));
    ...
}

Cela représente 99 % des chaînes visibles par l'utilisateur que vous êtes susceptible d'écrire. Pour plus d'informations sur le marquage des chaînes littérales traduisibles, voir Marquer les chaînes de texte de données traduisibles.

Si le texte cité ne se trouve pas dans une fonction membre d'une sous-classe QObject, utilisez soit la fonction tr() d'une classe appropriée, soit la fonction QCoreApplication::translate() directement :

void some_global_function(LoginWidget *logwid)
{
    QLabel *label = new QLabel(
                LoginWidget::tr("Password:"), logwid);
}

void same_global_function(LoginWidget *logwid)
{
    QLabel *label = new QLabel(
                QCoreApplication::translate("LoginWidget", "Password:"), logwid);
}

Basée sur l'ID qtTrId()

qtTrId() renvoie une chaîne traduite identifiée par l'ID. Ainsi, au lieu d'écrire la chaîne traduisible elle-même dans la fonction, vous écrivez l'ID de la traduction. Le texte source (chaîne par défaut) est écrit en utilisant la notation métastatique //%. Si le texte n'est pas traduit, le texte source annoté par //% est renvoyé. Si aucun identifiant correspondant n'est trouvé, l'identifiant lui-même est renvoyé. Cela ne devrait pas se produire dans des conditions normales.

//% "Password:"
QLabel *label = new QLabel(qtTrId("PasswordID"));

Ce code fait de "PasswordID" une entrée clé unique dans les fichiers source de traduction (TS) et écrit "Password :" comme texte source. Au moment de l'exécution, le système de traduction recherche l'ID "PasswordID" et obtient ensuite la valeur de traduction correspondante (ou, si elle n'est pas traduite, le texte source) pour la locale actuelle du système.

Remarque : si vous désactivez la conversion automatique de const char * à QString en compilant votre application avec la macro QT_NO_CAST_FROM_ASCII définie, vous récupérerez très probablement toutes les chaînes de caractères manquantes. Voir QString::fromUtf8() et QString::fromLatin1() pour plus d'informations.

Utiliser des paramètres au lieu de concaténer des chaînes de caractères

Les langues organisent différemment les mots dans les expressions, les clauses et les phrases. Ne créez donc pas de chaînes de caractères en concaténant des mots et des données. Utilisez plutôt % pour insérer des paramètres dans les chaînes.

Par exemple, dans la chaîne After processing file %1, file %2 is next in line, %1 et %2 sont des paramètres numérotés. Au moment de l'exécution, %1 et %2 sont remplacés respectivement par le premier et le deuxième nom de fichier. Les mêmes paramètres numérotés doivent apparaître dans la traduction, mais pas nécessairement dans le même ordre. Une traduction allemande de la chaîne peut inverser les phrases. Par exemple, Datei %2 wird bearbeitet, wenn Datei %1 fertig ist. Les deux paramètres numérotés apparaissent dans la traduction, mais dans l'ordre inverse.

QML : Utiliser .arg()

L'extrait QML suivant contient une chaîne avec deux paramètres numériques %1 et %2. Ces paramètres sont insérés avec les fonctions .arg().

Text {
    text: qsTr("File %1 of %2").arg(counter).arg(total)
}

%1 fait référence au premier paramètre et %2 fait référence au second paramètre, de sorte que ce code produit une sortie comme : Fichier 2 sur 3.

Évitez d'utiliser des chaînes de caractères modèles avec des arguments, car la chaîne résultante est définie au moment de l'exécution et non de la compilation. Par conséquent, les outils de traduction ne peuvent pas trouver la traduction correcte pour les chaînes modèles.

C++ : Utilisez QString::arg()

En C++, utilisez les fonctions QString::arg() pour remplacer les paramètres :

void FileCopier::showProgress(int done, int total,
                              const QString &currentFile)
{
    label.setText(tr("%1 of %2 files copied.\nCopying: %3")
                  .arg(done)
                  .arg(total)
                  .arg(currentFile));
}

Ce code produit des résultats tels que : 5 des 10 fichiers copiés. Copie : somefile.txt.

Gestion des formes plurielles

Vous pouvez passer un paramètre entier supplémentaire(n) aux fonctions de traduction et utiliser une notation spéciale pour les formes plurielles (%n) dans chaque chaîne traduisible.

En fonction de la valeur de n, la fonction de traduction renvoie une traduction différente, avec le numéro grammatical correct pour la langue cible. En outre, toute occurrence de %n est remplacée par la valeur de n.

Par exemple, les traductions anglaise et française de la chaîne %n message(s) saved requièrent des formes plurielles différentes.

nPas de traductionFrançaisAnglais
0"0 message(s) sauvegardé(s)"0 message sauvegardé""0message (s) sauvegardé(s )
1"1 message(s) sauvegardé(s)"1 message sauvegardé""1 message sauvegardé
2"2 message(s) sauvegardé(s)""2messages sauvegardés""2messages sauvegardés"
37"37 message(s) sauvegardé(s)""37messages sauvegardés""37messages sauvegardés"

Cette expression idiomatique fonctionne également dans les langues cibles qui ont plusieurs formes de pluriel, comme une forme duale. En outre, l'idiome traite correctement le cas n == 0 pour les langues telles que le français qui exigent le singulier.

Pour un résumé des règles que Qt Linguist et lrelease utilisent pour traduire les chaînes contenant des formes plurielles, voir Règles de traduction pour les formes plurielles.

Pour gérer les formes plurielles dans la langue maternelle, chargez un fichier TS pour cette langue également. Utilisez l'outil lupdate ou l'option de ligne de commande -pluralonly pour créer des fichiers TS qui ne contiennent que des entrées avec des formes plurielles.

Vous pouvez également utiliser l'option de ligne de commande -pluralonly de l'outil lconvert pour supprimer toutes les formes non plurielles d'un fichier TS existant.

Exemple QML

L'extrait de code QML suivant traduit le texte source dans la forme plurielle correcte et remplace %n par la valeur de total:

Text {
    text: qsTr("%n message(s) saved", "", total)
}

Exemple C++

L'extrait de code C++ suivant remplace %n par la valeur renvoyée par la fonction count():

int n = messages.count();
showMessage(tr("%n message(s) saved", "", n));

Utiliser les paramètres régionaux de numérotation

Si vous incluez le modificateur %L lorsque vous spécifiez un paramètre, le nombre est localisé en fonction des paramètres régionaux actuels. La conversion utilise les paramètres régionaux par défaut si vous les avez définis ou les paramètres régionaux du système dans le cas contraire.

QML : utiliser %L

Par exemple, dans l'extrait QML suivant, %L1 formate le premier paramètre selon les conventions de formatage des nombres de la locale (région géographique) actuellement sélectionnée :

Text {
    text: qsTr("%L1").arg(total)
}

Si total est le nombre 4321.56, avec les paramètres régionaux anglais (locale), la sortie est 4,321.56, tandis qu'avec les paramètres régionaux allemands, elle est 4.321,56.

C++ : Utilisez %Ln

En C++, vous pouvez utiliser %Ln pour produire une représentation localisée de n. Utilisez QLocale::setDefault() pour définir la locale par défaut.

Internationalisation de la date, de l'heure et de la monnaie

Présentez la date, l'heure et la monnaie en utilisant les formats locaux préférés.

QML : utiliser les fonctions QtQml

QML ne dispose pas de modificateurs spéciaux dans les chaînes de caractères pour formater les dates et les heures. Au lieu de cela, vous devez interroger la locale actuelle (région géographique) et utiliser les méthodes de Date pour formater la chaîne.

Qt.locale() renvoie un objet Locale qui contient des informations sur la locale. En particulier, la propriété Locale.name contient la langue et le pays de la locale actuelle. Vous pouvez utiliser la valeur telle quelle ou l'analyser pour déterminer le contenu approprié pour la locale actuelle.

L'extrait suivant obtient la date et l'heure actuelles à l'aide de Date(), puis les convertit en une chaîne de caractères correspondant à la locale actuelle. Il insère ensuite la chaîne de date dans le paramètre %1 pour la traduction appropriée.

Text {
    text: qsTr("Date %1").arg(Date().toLocaleString(Qt.locale()))
}

Pour localiser les nombres en devises, utilisez le type Number. Il dispose de fonctions similaires à celles du type Date pour convertir les nombres en chaînes de devises localisées.

C++ : Utilisez la classe QLocale

En C++, utilisez QLocale::timeFormat() ou QLocale::toString(QTime) ou toString(QDate):

QLabel *label = new QLabel(this);
label->setText(tr("Date %1").arg(QLocale().toString(QDate::currentDate()));

Marquer les chaînes de texte de données traduisibles

Utilisez les fonctions _NOOP (en QML) et les macros _NOOP (en C++) pour marquer les chaînes de caractères traduisibles en vue de leur extraction par l'outil lupdate.

QML : Utiliser les fonctions _NOOP

En QML, utilisez les fonctions suivantes pour marquer les chaînes de caractères traduisibles :

Si l'utilisateur change la langue du système sans redémarrer, il se peut, selon le système, que les chaînes de caractères des tableaux, des modèles de liste et d'autres structures de données ne soient pas actualisées automatiquement. Pour forcer l'actualisation des textes lorsqu'ils sont affichés dans l'interface utilisateur, vous devez déclarer les chaînes à l'aide de la fonction QT_TR_NOOP(). Ensuite, lorsque vous remplissez les objets pour l'affichage, vous devez récupérer explicitement la traduction pour chaque texte.

En voici un exemple :

ListModel {
    id: myListModel

    ListElement {
        //: Capital city of Finland
        name: QT_TR_NOOP("Helsinki")
    }
}

...

Text {
    text: qsTr(myListModel.get(0).name)
    // Get the translation of the name property in element 0
}

C++ : Utiliser les macros _NOOP

Pour un texte traduisible complètement en dehors d'une fonction, utilisez les macros QT_TR_NOOP(), QT_TRID_NOOP() et QT_TRANSLATE_NOOP() qui s'étendent uniquement au texte sans le contexte.

Exemple de QT_TR_NOOP():

QString FriendlyConversation::greeting(int type)
{
    static const char *greeting_strings[] = {
        QT_TR_NOOP("Hello"),
        QT_TR_NOOP("Goodbye")
    };
    return tr(greeting_strings[type]);
}

Un exemple de QT_TRANSLATE_NOOP():

static const char *greeting_strings[] = {
    QT_TRANSLATE_NOOP("FriendlyConversation", "Hello"),
    QT_TRANSLATE_NOOP("FriendlyConversation", "Goodbye")
};

QString FriendlyConversation::greeting(int type)
{
    return tr(greeting_strings[type]);
}

QString global_greeting(int type)
{
    return QCoreApplication::translate("FriendlyConversation",
                                       greeting_strings[type]);
}

Ajouter des commentaires pour les traducteurs

Vous pouvez ajouter des commentaires dans le code source avant une chaîne de caractères que vous marquez comme traduisible afin d'en clarifier le but. Les commentaires sont inclus dans les fichiers TS que vous livrez au traducteur.

Remarque : les fichiers TS sont des fichiers XML contenant le texte source et un emplacement pour le texte traduit. Les fichiers TS mis à jour sont convertis en fichiers de traduction binaires et inclus dans l'application finale.

QML : Utiliser // : et //~

Dans l'extrait de code suivant, le texte de la ligne //: est le commentaire principal du traducteur.

Le texte de la ligne //~ est une information supplémentaire facultative. Le premier mot du texte est utilisé comme identifiant supplémentaire dans l'élément XML du fichier TS ; assurez-vous donc que le premier mot ne fait pas partie de la phrase. Par exemple, le commentaire Context Not related to back-stepping est converti en <extra-Context>Not related to back-stepping dans le fichier TS.

Text {
    id: txt1;
    // This UI string is only used here
    //: The back of the object, not the front
    //~ Context Not related to back-stepping
    text: qsTr("Back");
}

C++ : Utiliser les caractères de commentaire

Pour ajouter des commentaires en C++, annotez les appels tr() dans votre code avec des commentaires de la forme //: ou en marquant le début et la fin du commentaire.

Dans les exemples suivants, les commentaires sont associés aux chaînes transmises à tr() dans le contexte de chaque appel :

//: This name refers to a host name.
hostNameLabel->setText(tr("Name:"));

/*: This text refers to a C++ code example. */
QString example = tr("Example");

Pour ajouter des commentaires facultatifs, utilisez :

//~ <field name> <field contents>

Le nom du champ doit être composé d'un préfixe de domaine (éventuellement l'extension conventionnelle du format de fichier dont le champ s'inspire), d'un trait d'union et du nom réel du champ en notation délimitée par des tirets bas. Pour le stockage dans des fichiers TS, le nom du champ et le préfixe extra- formeront un nom d'élément XML. Le contenu du champ sera encapsulé dans le XML, mais apparaîtra par ailleurs textuellement comme le contenu de l'élément. Vous pouvez ajouter un nombre illimité de champs uniques à chaque message.

Exemple :

//: This is a comment for the translator.
//~ loc-layout_id foo_dialog
//~ loc-blank False
//~ magic-stuff This might mean something magic.
QString text = MyMagicClass::tr("Sim sala bim.");

Note : L'utilisation des commentaires de //= metastring pour définir les ID des traductions textuelles est dépréciée dans Qt 6.10, et sera supprimée dans les prochaines versions.

Vous pouvez utiliser le mot-clé TRANSLATOR pour les commentaires du traducteur. Les métadonnées apparaissant juste devant le mot-clé TRANSLATOR s'appliquent à l'ensemble du fichier TS.

Note : Lorsque le fichier TS est ouvert dans Qt Linguist, les commentaires annotés par //: sont présentés dans l'éditeur de messages de Qt Linguist. Par contre, les textes fournis à l'aide des notations de //~ sont des informations supplémentaires et sont générés dans le fichier TS uniquement. Ils sont principalement destinés aux conversions vers d'autres formats et sont cachés dans Qt Linguist.

Regroupement des traductions basées sur des identifiants

Vous pouvez attribuer une étiquette à chaque traduction basée sur l'ID afin d'organiser les entrées basées sur l'ID de grands projets en groupes plus petits.

Pour attribuer un label à une entrée basée sur l'ID, ajoutez un commentaire //@ nommant le label, par exemple en C++ :

//% "Open file"
//@ FileOperations
qtTrId("msg.open");

ou en QML :

//% "Open file"
//@ FileOperations
qsTrId("msg.open");

Lorsque vous ouvrez le fichier TS dans Qt Linguistles entrées basées sur l'ID ayant la même étiquette sont regroupées, de la même manière que les entrées basées sur le texte sont regroupées par contexte. Tout élément sans étiquette apparaît sous <unnamed label>.

Remarque : les noms des étiquettes n'ont aucun effet sur la consultation ou l'unicité : Les identifiants restent globalement uniques et peuvent toujours être chargés via qtTrId("msgid") sans faire référence à une étiquette. L'étiquette n'est utilisée que pour améliorer la navigation du traducteur et ne modifie pas le comportement en cours d'exécution.

Désambiguïser les textes identiques

Le système de traduction consolide les chaînes de texte de l'interface utilisateur en éléments uniques afin d'éviter de devoir traduire le même texte plusieurs fois. Cependant, un texte peut sembler identique à un autre texte mais avoir une signification différente. Par exemple, en anglais, back signifie à la fois un pas en arrière et la partie d'un objet opposée à l'avant. Vous devez indiquer au système de traduction ces deux significations distinctes, afin que le traducteur puisse créer deux traductions distinctes.

QML : Ajouter un désambiguïsateur à qsTr()

En QML, ajoutez une chaîne de désambiguïsation comme deuxième paramètre de la fonction qsTr().

Dans l'extrait de code suivant, l'ID not front différencie ce texte Back du texte Back backstepping :

Text {
    id: txt1
    // This UI string is used only here
    //: The back of the object, not the front
    //~ Context Not related to back-stepping
    text: qsTr("Back", "not front")
}

C++ : Ajouter un désambiguïsateur à tr()

En C++, il est possible de passer une chaîne de caractères désambiguïsante dans l'appel à la fonction tr().

Dans l'extrait de code suivant, l'ID recipient différencie le nom du destinataire de celui de l'expéditeur :

MyWindow::MyWindow()
{
    QLabel *senderLabel = new QLabel(tr("Name:"));
    QLabel *recipientLabel = new QLabel(tr("Name:", "recipient"));
    ...

Rendre les raccourcis clavier traduisibles

Dans sa forme la plus courante, un raccourci clavier décrit une combinaison de touches sur laquelle vous appuyez pour effectuer une action. Pour standard shortcuts, utilisez une touche standard pour demander la séquence de touches spécifique à la plate-forme associée à chaque raccourci.

Pour les raccourcis personnalisés, utilisez des chaînes lisibles par l'homme, telles que Ctrl+Q ou Alt+F. Vous pouvez les traduire en raccourcis appropriés pour les locuteurs de différentes langues.

Si les raccourcis clavier sont codés en dur dans votre application, les traducteurs ne peuvent pas les remplacer.

Lorsque vous utilisez des raccourcis clavier dans le texte des éléments de menu et des boutons, un caractère mnémotechnique (souligné) indique qu'en appuyant sur Alt ou Ctrl avec le caractère souligné, vous effectuez la même action qu'en cliquant sur l'élément de menu ou en appuyant sur le bouton.

Par exemple, les applications utilisent souvent F comme caractère mnémonique dans le menu File, de sorte que vous pouvez soit cliquer sur l'élément de menu, soit appuyer sur Alt+F pour ouvrir le menu. Pour définir le caractère mnémonique dans la chaîne traduisible ("File"), préfixez-le par une esperluette : "&File". La traduction de la chaîne doit également comporter une esperluette, de préférence devant le même caractère.

Exemple en QML

En QML :

Menu {
    id: fileMenu
    title: qsTr("&File")

    MenuItem {
        objectName: "quitMenuItem"
        text: qsTr("E&xit")
        onTriggered: Qt.quit()
    }
}

C++ : Utiliser la classe QKeySequence

En C++, utilisez les objets QAction et QKeySequence pour spécifier les raccourcis clavier qui déclenchent des actions :

exitAct = new QAction(tr("E&xit"), this);
exitAct->setShortcuts(QKeySequence::Quit);

Les traductions des raccourcis clavier sont associées au contexte QShortcut.

Utiliser Locale pour étendre les fonctionnalités de localisation

Il se peut que des graphiques ou des sons différents soient mieux adaptés à des régions géographiques différentes.

D'une manière générale, évitez de localiser les images. Créez des icônes adaptées au monde entier, plutôt que de vous fier à des jeux de mots locaux ou à des métaphores exagérées. Toutefois, il se peut que vous deviez inverser les images des flèches pointant vers la gauche et vers la droite pour les régions arabes et hébraïques.

La locale est l'un des sélecteurs de fichiers par défaut, de sorte que vous pouvez utiliser la sélection de fichiers pour afficher différentes images que vous fournissez en tant que ressources en fonction de la locale du système.

Les exemples de code QML et C++ présentés dans les sections suivantes supposent que vous livrez les fichiers suivants dans les ressources de l'application et que vous utilisez les codes de langue et de pays comme noms de sous-dossiers :

images
├── language-icon.png
├── +en_GB
│   └── language-icon.png
└── +fi_FI
    └── language-icon.png

QML : Définir la source de l'image

L'extrait de code QML suivant montre comment sélectionner une image source d'icône en fonction de la locale actuelle :

icon.source: "qrc:/images/language-icon.png"

C++ : Utiliser QFileSelector

L'extrait de code C++ suivant utilise QFileSelector pour sélectionner une icône de langue dans le dossier images en fonction des paramètres linguistiques du système :

const QFileSelector selector;
const QIcon languageIcon(selector.select(":/images/language-icon.png"));

Activer la traduction

Les noms des fichiers TS doivent contenir les codes ISO de langue et de pays :

  • langue est un code de langue ISO-639 en minuscules.
  • country est un code de pays ISO-3166 à deux lettres en majuscules.

Par exemple, qml_de.ts définit la langue cible comme étant l'allemand, et qml_de_CH.ts définit la langue cible comme étant l'allemand et le pays cible comme étant la Suisse. L'outil lrelease génère des fichiers QM appelés qml_de.qm et qml_de_CH.qm que l'application charge en fonction des paramètres linguistiques du système.

QML : Utiliser QQmlApplicationEngine

En QML, utilisez QQmlApplicationEngine pour charger automatiquement les fichiers de traduction à partir d'un sous-répertoire appelé i18n dans le répertoire qui contient le fichier QML principal. Les noms des fichiers de traduction doivent être précédés du préfixe qml_. Par exemple, qml_en_US.qm. Les extraits de code CMake suivants expliquent comment configurer une application multilingue :

...
find_package(Qt6 6.5 REQUIRED COMPONENTS Quick LinguistTools)
qt_standard_project_setup(REQUIRES 6.5 I18N_TRANSLATED_LANGUAGES ja_JP)

qt_add_qml_module(appmultilingual_demo
    URI multilingual_demo
    QML_FILES
        Main.qml
)

qt_add_translations(appmultilingual_demo
    TS_FILE_BASE qml
    TS_FILE_DIR i18n
    RESOURCE_PREFIX /qt/qml/multilingual_demo/i18n
)
...

Les applications rechargent les traductions lorsque la valeur de la propriété QJSEngine::uiLanguage ou Qt.uiLanguage change. L'extrait de code suivant change la langue dynamiquement lorsque l'utilisateur clique sur le bouton :

Button {
    anchors.centerIn: parent
    text: qsTr("Translate")
    onClicked: {
        Qt.uiLanguage = Qt.uiLanguage === "en" ? "ja" : "en"
    }
}

C++ : Utiliser QTranslator

En C++, les noms de fichiers TS doivent contenir le nom de l'application. Par exemple, app_de_DE.ts.

En règle générale, la fonction main() de votre application Qt C++ ressemble à ceci :

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QTranslator myappTranslator;
    if (myappTranslator.load(QLocale::system(), u"myapp"_s, u"_"_s, u":/i18n"_s))
        app.installTranslator(&myappTranslator);

    return app.exec();
}

Pour une application sensible à la traduction, vous créez un objet QTranslator, load une traduction en fonction de la locale d'affichage de l'interface utilisateur au moment de l'exécution, et vous installez l'objet traducteur dans l'application.

Se préparer aux changements dynamiques de langue

Les objets Qt Widgets et Qt Quick utilisent le système d'événements de Qt XML pour informer les classes des changements de traduction.

LanguageChange Les événements sont affichés lorsque vous utilisez la fonction QCoreApplication::installTranslator() pour installer une nouvelle traduction. D'autres composants de l'application peuvent également forcer les widgets ou les types QML dérivés du type Item à se mettre à jour en leur envoyant des événements LanguageChange.

Par défaut, les événements LanguageChange sont propagés à toutes les fenêtres de premier niveau et, de là, à l'ensemble de l'arborescence des widgets ou des types QML dérivés de Item.

Qt Widgets: Surcharger changeEvent

Le gestionnaire d'événements par défaut des sous-classes QWidget répond à l'événement QEvent::LanguageChange et appelle la fonction changeEvent() si nécessaire.

Pour que les Qt Widgets soient au courant des modifications apportées aux objets QTranslator installés, réimplémentez la fonction changeEvent() du widget pour vérifier si l'événement est un événement LanguageChange et mettez à jour le texte affiché par les widgets à l'aide de la fonction tr(). Par exemple :

void MyWidget::changeEvent(QEvent *event)
{
    if (event->type() == QEvent::LanguageChange) {
        titleLabel->setText(tr("Document Title"));
        ...
        okPushButton->setText(tr("&OK"));
    } else
        QWidget::changeEvent(event);
}

Lorsque vous utilisez les fichiers d'interface utilisateur Qt Widgets Designer (.ui) et uic, vous pouvez lire les nouveaux fichiers de traduction et appeler directement ui.retranslateUi(this):

void MyWidget::changeEvent(QEvent *event)
{
    if (event->type() == QEvent::LanguageChange) {
        ui.retranslateUi(this);
    } else
        QWidget::changeEvent(event);
}

Pour transmettre d'autres événements de changement, appelez l'implémentation par défaut de la fonction.

La liste des traducteurs installés peut changer en réponse à un événement LocaleChange, ou l'application peut fournir une interface utilisateur qui permet à l'utilisateur de changer la langue de l'application en cours.

QML : Événement Override pour les types dérivés de Item

Pour les applications QML simples sans types personnalisés C++ enregistrés, l 'utilisation de QQmlApplicationEngine suffit à déclencher une mise à jour de toutes les liaisons de traduction.

Toutefois, si vous avez enregistré un type dérivé de QQuickItem et que l'une de ses propriétés expose du texte traduit (ou dépend d'une autre langue), remplacez son event method et émettez le signal de changement de la propriété (ou appelez notify dans le cas de propriétés liables). A titre d'exemple :

class MyItem : public QQuickItem
{
    Q_OJBECT
    QML_ELEMENT

    Q_PROPERTY(QString greeting READ greeting NOTIFY greetingChanged)

public signals:
    void greetingChanged();
public:
    QString greeting() const
    {
        return tr("Hello World!");
    }

    bool event(QEvent *ev) override
    {
        if (ev->type() == QEvent::LanguageChange)
            emit greetingChanged();
        return QQuickItem::event(ev);
    }
};

Cela garantit que toute liaison en QML dans laquelle la propriété est utilisée est réévaluée et prend en compte le changement de langue.

Classes génériques dérivées de QObject : Utiliser les filtres d'événements

Certaines classes ne sont pas dérivées de QWidget ni de QQuickItem, mais peuvent tout de même avoir besoin de gérer des événements de changement de langue. Dans ce cas, installez un filtre d'événements sur QCoreApplication.

class CustomObject : public QObject
{
    Q_OBJECT

public:
    QList<QQuickItem *> managedItems;

    CustomObject(QOject *parent = nullptr) : QObject(parent)
    {
        QCoreApplication::instance()->installEventFilter(this);
    }

    bool eventFilter(QObject *obj, QEvent *ev) override
    {
        if (obj == QCoreApplication::instance() && ev->type() == QEvent::LanguageChange) {
            for (auto item : std::as_const(managedItems))
                QCoreApplication::sendEvent(item, ev);
            // do any further work on reaction, e.g. emit changed signals
        }
        return false;
    }
};

Cela peut s'avérer nécessaire lorsque la classe fournit des chaînes traduites qui sont ensuite affichées dans une interface utilisateur (par exemple, une page personnalisée item model), ou lorsque la classe agit en tant que conteneur de Widgets ou d'éléments rapides et est donc responsable de la transmission de l'événement à ces derniers.

Considérations supplémentaires pour le code C

Les sections suivantes contiennent plus d'informations sur l'utilisation des classes et fonctions Qt C++ dans les applications traduisibles :

Utiliser QString pour tout le texte visible par l'utilisateur

QString utilise l'encodage Unicode en interne, et vous pouvez donc utiliser des opérations de traitement de texte familières pour traiter de manière transparente toutes les langues du monde. De plus, comme toutes les fonctions Qt qui présentent du texte à l'utilisateur prennent un objet QString en paramètre, il n'y a pas de frais de conversion de char * à QString.

Définir un contexte de traduction

Le contexte de traduction pour QObject et chaque sous-classe de QObject est le nom de la classe elle-même. Si vous sous-classez QObject, utilisez la macro Q_OBJECT dans la définition de la classe pour remplacer le contexte de traduction. La macro définit le contexte comme étant le nom de la sous-classe.

Par exemple, la définition de classe suivante inclut la macro Q_OBJECT, implémentant une nouvelle fonction tr() qui utilise le contexte MainWindow:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow();
    ...

Si vous n'utilisez pas Q_OBJECT dans une définition de classe, le contexte est hérité de la classe de base. Par exemple, étant donné que toutes les classes basées sur QObject dans Qt fournissent un contexte, une nouvelle sous-classe QWidget définie sans macro Q_OBJECT utilise le contexte QWidget si vous invoquez sa fonction tr().

Traduire les classes non Qt

Vous devez fournir des informations supplémentaires à lupdate sur les chaînes de caractères dans les classes qui n'héritent pas de QObject ou qui n'utilisent pas la macro Q_OBJECT. Pour ajouter la prise en charge de la traduction à une classe non-Qt, vous pouvez utiliser la macro Q_DECLARE_TR_FUNCTIONS(). En voici un exemple :

class MyClass
{
    Q_DECLARE_TR_FUNCTIONS(MyClass)

public:
    MyClass();
    ...
};

Cette macro fournit à la classe des fonctions tr() que vous pouvez utiliser pour traduire les chaînes de caractères associées à la classe et permet à lupdate de trouver des chaînes de caractères traduisibles dans le code source.

Vous pouvez également appeler la fonction QCoreApplication::translate() avec un contexte spécifique que lupdate et Qt Linguist reconnaissent.

Traduire un texte qui n'appartient pas à une sous-classe de QObject

Si le texte cité ne se trouve pas dans une fonction membre d'une sous-classe QObject, utilisez soit la fonction tr() d'une classe appropriée, soit la fonction QCoreApplication::translate() directement :

void some_global_function(LoginWidget *logwid)
{
    QLabel *label = new QLabel(
            LoginWidget::tr("Password:"), logwid);
}

void same_global_function(LoginWidget *logwid)
{
    QLabel *label = new QLabel(
            QCoreApplication::translate("LoginWidget", "Password:"),
            logwid);
}

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.