Rédaction du code source en vue de la traduction
Écrivez le code source QML et Qt C++ de manière à permettre la localisation des applications :
- Marquer les chaînes à traduire
- Utilisez des paramètres plutôt que de concaténer des chaînes de caractères
- Gérer les formes plurielles
- Utilisez les paramètres régionaux pour les nombres
- Internationalisez les dates, l'heure et les devises
- Marquer les chaînes de texte contenant des données traduisibles
- Ajouter des commentaires à l'intention des traducteurs
- Désambiguïser les textes identiques
- Rendre les raccourcis clavier traduisibles
- Utiliser les paramètres régionaux pour étendre les fonctionnalités de localisation
- Activer la traduction
- Préparer les changements de langue dynamiques
Lors du développement d’applications C++, consultez également la section « Considérations supplémentaires pour le code C++ ».
Marquer les chaînes à traduire
La plupart des textes devant être traduits dans une application sont constitués soit de mots isolés, soit de courtes phrases. Ceux-ci apparaissent généralement sous forme de titres de fenêtres, d'éléments de menu, d'infobulles et d'étiquettes associées à des boutons, des cases à cocher et des boutons radio.
Qt minimise l'impact sur les performances lié à l'utilisation des traductions en traduisant les phrases de chaque fenêtre au fur et à mesure de leur création. 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 surcoût d’exécution pour les fenêtres traduites. Seules les fenêtres qui sont créées, détruites puis recréées entraîneront un coût de performance lié à la traduction.
Vous pouvez créer des applications qui changent de langue à l’exécution, mais cela demande un certain effort et entraîne 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 : l’approche basée sur le texte et celle basée sur les identifiants.
Dans l’approche de traduction basée sur le texte, Qt indexe chaque chaîne traduisible en fonction du contexte de traduction et, éventuellement, d’un commentaire de désambiguïsation qui lui est associé. Une même phrase peut apparaître dans plusieurs contextes sans créer de conflit. Si une phrase apparaît plusieurs fois dans un contexte donné, elle n’est traduite qu’une seule fois et la traduction est appliquée à toutes ses occurrences au sein de ce contexte.
Dans l’approche de traduction basée sur les identifiants, chaque traduction est identifiée de manière unique par un identifiant explicite. Les identifiants sont uniques à l’échelle du projet. Si un identifiant apparaît plusieurs fois dans un projet, il n’est traduit qu’une seule fois et la traduction est appliquée à toutes ses occurrences au sein du 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 textuelle
- qsTranslate(): Traduction basée sur le texte
- qsTrId(): Traduction basée sur les identifiants
qsTr() basée sur le 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), puis récupère la valeur de traduction correspondante pour les paramètres régionaux actuels du système. Le résultat est renvoyé à la propriété « text » et l’interface utilisateur affiche la traduction appropriée de « Back » pour les paramètres régionaux actuels. Si aucune traduction n’est trouvée, « qsTr() » renvoie la chaîne d’origine.
Le contexte de traduction peut être défini pour un fichier donné à l’aide de :
pragma Translator: ChosenContextou
pragma Translator: "Chosen::Context"Le contexte défini via ` qsTranslate() ` a priorité sur celui défini via ` pragma ` Translator. En QML, par défaut, le contexte de traduction correspond au nom du fichier.
qsTrId() basé sur un identifiant :
Text {
id: txt1
//% "Back"
text: qsTrId("BackID")
}Ce code fait de « BackID » une clé unique dans les fichiers source de traduction (TS) et écrit « Back » comme texte source. Lors de l’exécution, le système de traduction recherche l’ID « BackID », puis récupère la valeur de traduction correspondante (ou, si elle n’est pas traduite, le texte source) pour les paramètres régionaux actuels 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 portant 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 visibles par l’utilisateur en vue de leur traduction :
- tr(): Traduction textuelle
- QCoreApplication::translate(): Traduction textuelle
- QTranslator::translate(): Traduction basée sur le texte
- qtTrId(): Traduction basée sur les identifiants
- Pour plus d'options, consultez la page linguist-id-based-i18n.html
tr() basé sur le texte
Utilisez la fonction ` tr()` pour marquer du texte comme traduisible et pour afficher le texte traduit. Le contexte de traduction est le nom de la sous-classe de ` QObject ` dans laquelle la chaîne est utilisée. Pour définir le contexte de traduction pour les nouvelles classes basées sur ` QObject`, utilisez la macro ` Q_OBJECT ` dans chaque nouvelle définition de classe.
Lorsque la méthode ` tr() ` est appelée, elle recherche la chaîne traduisible à l’aide d’un objet ` QTranslator `, que vous devez installer sur l’objet `Application`, comme décrit dans la section « Activer la traduction ».
Par exemple, en supposant que ` LoginWidget ` soit une sous-classe de ` QWidget` :
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 littéraux de chaîne comme traduisibles, consultez la section « Marquer les chaînes de données comme traduisibles ».
Si le texte entre guillemets ne se trouve pas dans une fonction membre d’une sous-classe de ` QObject `, utilisez soit la fonction ` tr() ` d’une classe appropriée, soit directement la fonction ` QCoreApplication::translate()` :
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);
}qtTrId() basée sur l’ID
qtTrId() renvoie une chaîne traduite identifiée par un 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éta-chaîne //%. Si le texte n’est pas traduit, le texte source annoté par //% est renvoyé. Si aucun ID correspondant n’est trouvé, l’ID lui-même est renvoyé. Cela ne devrait pas se produire dans des conditions normales.
Ce code fait de « PasswordID » une clé unique dans les fichiers de 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 », puis récupère la valeur de traduction correspondante (ou, si elle n’est pas traduite, le texte source) pour les paramètres régionaux actuels du système.
Remarque : si vous désactivez la conversion automatique de const char * en QString en compilant votre application avec la macro QT_NO_CAST_FROM_ASCII définie, vous repérerez très probablement les chaînes manquantes. Consultez QString::fromUtf8() et QString::fromLatin1() pour plus d’informations.
Utilisez des paramètres plutôt que de concaténer des chaînes de caractères
Les différentes langues organisent les mots différemment dans les expressions, les propositions et les phrases ; évitez donc de créer des 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 de caractères.
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. Lors de l’exécution, %1 et %2 sont remplacés respectivement par les premier et deuxième noms de fichiers. 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 cette chaîne pourrait inverser l'ordre des expressions. 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 : utilisation de .arg()
L'extrait de code QML suivant contient une chaîne comportant deux paramètres numérotés : %1 et %2. Ces paramètres sont insérés à l'aide des fonctions .arg().
Text {
text: qsTr("File %1 of %2").arg(counter).arg(total)
}%1 fait référence au premier paramètre et %2 au deuxième paramètre ; ce code produit donc un résultat du type : Fichier 2 sur 3.
Évitez d’utiliser des chaînes de caractères avec des arguments, car la chaîne résultante est définie lors de l’exécution, et non lors de la compilation. Par conséquent, les outils de traduction ne peuvent pas trouver la traduction correcte pour ces chaînes.
C++ : utilisez QString::arg()
En C++, utilisez les fonctions QString::arg() pour substituer les paramètres :
void FileCopier::showProgress(int done, int total,
const QString ¤tFile)
{
label.setText(tr("%1 of %2 files copied.\nCopying: %3")
.arg(done)
.arg(total)
.arg(currentFile));
}Ce code génère une sortie du type : 5 fichiers sur 10 copiés. Copie en cours : somefile.txt.
Gérer les 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 nombre grammatical correct pour la langue cible. De plus, toute occurrence de « %n » est remplacée par la valeur de n.
Par exemple, les traductions en anglais et en français de la chaîne « %n message(s) saved » nécessitent des formes plurielles différentes.
| n | Pas de traduction | Français | Anglais |
|---|---|---|---|
| 0 | « 0 message(s) enregistré(s) » | « 0 message enregistré » | « 0message (s) enregistré(s) » |
| 1 | « 1 message(s) enregistré(s) » | « 1 message sauvegardé » | « 1 message enregistré » |
| 2 | « 2 messages enregistrés » | « 2messagessauvegardés » | « 2messages enregistrés » |
| 37 | « 37 message(s) enregistrés » | « 37messagessauvegardés » | « 37messages enregistrés » |
Cette expression fonctionne également avec les langues cibles qui possèdent plusieurs formes de pluriel, comme la forme duelle. De plus, elle gère correctement le cas des n- == 0 s pour les langues telles que le français qui exigent le singulier.
Pour un résumé des règles utilisées par Qt Linguist et lrelease pour traduire les chaînes contenant des formes plurielles, consultez la section « Règles de traduction pour les formes plurielles ».
Pour gérer les formes plurielles dans la langue source, chargez également un fichier TS pour cette langue. Utilisez l’option de ligne de commande -pluralonly de l’outil lupdate pour créer des fichiers TS ne contenant 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 en utilisant la forme plurielle correcte et remplace %n par la valeur de total:
Text {
text: qsTr("%n message(s) saved", "", total)
}Exemple en 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));Utilisation des paramètres régionaux de numération
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 la locale par défaut si vous l'avez définie, ou sinon la locale système.
QML : Utiliser %L
Par exemple, dans l’extrait de code 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 correspond au nombre 4321,56, avec les paramètres régionaux (locale) anglais, le résultat est 4 321,56, tandis qu’avec les paramètres régionaux allemands, il est 4 321,56.
C++ : Utilisez %Ln
En C++, vous pouvez utiliser ` %Ln ` pour générer 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 devise
Affichez la date, l’heure et les devises en utilisant les formats préférés localement.
QML : utilisez les fonctions QtQml
QML ne dispose pas de modificateurs spéciaux à intégrer dans les chaînes de caractères pour le formatage des dates et des heures. À la place, vous devez interroger les paramètres régionaux actuels (région géographique) et utiliser les méthodes de la classe Date pour formater la chaîne.
Qt.locale() renvoie un objet ` Locale ` contenant des informations sur les paramètres régionaux. En particulier, la propriété ` Locale.name ` contient la langue et le pays des paramètres régionaux actuels. Vous pouvez utiliser cette valeur telle quelle ou l’analyser pour déterminer le contenu approprié aux paramètres régionaux actuels.
L'extrait de code suivant récupère la date et l'heure actuelles à l'aide de ` Date()`, puis les convertit en une chaîne adaptée à la locale actuelle. Il insère ensuite cette chaîne de date dans le paramètre ` %1 ` pour obtenir la traduction appropriée.
Text {
text: qsTr("Date %1").arg(Date().toLocaleString(Qt.locale()))
}Pour localiser les montants monétaires, utilisez le type `Number`. Il dispose de fonctions similaires à celles du type ` Date ` pour convertir les nombres en chaînes de caractères monétaires localisées.
C++ : utilisation de 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 traduisibles
Utilisez les fonctions _NOOP (en QML) et les macros _NOOP (en C++) pour marquer les littéraux de chaîne traduisibles afin qu’ils soient extraits par l’outil lupdate.
QML : Utilisez les fonctions _NOOP
En QML, utilisez les fonctions suivantes pour marquer les chaînes littérales traduisibles :
Si l'utilisateur modifie la langue du système sans redémarrer, selon le système, les chaînes contenues dans les tableaux, les modèles de liste et d'autres structures de données peuvent ne pas être actualisées automatiquement. Pour forcer l'actualisation des textes lorsqu'ils s'affichent 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 en vue de leur affichage, vous devez récupérer explicitement la traduction de chaque texte.
Par 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++ : Utilisation des macros _NOOP
Pour les textes traduisibles situés entièrement en dehors d’une fonction, utilisez les macros ` QT_TR_NOOP()`, ` QT_TRID_NOOP()` et ` QT_TRANSLATE_NOOP()`, qui se développent en affichant uniquement le texte sans le contexte.
Exemple d’utilisation 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]);
}Exemple d'utilisation 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 que vous marquez comme traduisible afin d’en clarifier l’objectif. Ces commentaires sont inclus dans les fichiers TS que vous fournissez au traducteur.
Remarque : les fichiers TS sont des fichiers XML contenant les textes sources et un emplacement réservé au texte traduit. Les fichiers TS mis à jour sont convertis en fichiers de traduction binaires et intégrés à l’application finale.
QML : Utilisez //: et //~
Dans l’extrait de code suivant, le texte de la ligne « //: » constitue le commentaire principal destiné au traducteur.
Le texte de la ligne « //~ » constitue une information supplémentaire facultative. Le premier mot du texte sert d’identifiant supplémentaire dans l’élément XML du fichier TS ; veillez donc à ce que ce premier mot ne fasse 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++ : utilisation des 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 tiret et du nom du champ proprement dit, séparé par des traits de soulignement. Pour le stockage dans des fichiers TS, le nom de champ, associé au préfixe extra-, formera un nom d’élément XML. Le contenu du champ sera échappé au format XML, mais apparaîtra par ailleurs tel quel en tant que 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.");Remarque : l'utilisation de commentaires sous forme de métacharaktères « //= » pour définir des identifiants pour les traductions textuelles est obsolète dans Qt 6.10 et sera supprimée dans les prochaines versions.
Vous pouvez utiliser le mot-clé TRANSLATOR pour les commentaires de traduction. Les métadonnées figurant juste avant le mot-clé TRANSLATOR s'appliquent à l'ensemble du fichier TS.
Remarque : lorsque le fichier TS est ouvert dans Qt Linguist, les commentaires annotés par //: s’affichent dans l’éditeur de messages de Qt Linguist. En revanche, les textes fournis à l’aide des notations //~ constituent des informations supplémentaires et ne sont générés que dans le fichier TS. Ils sont principalement destinés à la conversion vers d’autres formats et sont masqués dans Qt Linguist.
Regroupement des traductions basées sur des identifiants
Vous pouvez attribuer une étiquette à chaque traduction basée sur un ID afin d’organiser les entrées basées sur des ID de grands projets en groupes plus petits.
Pour attribuer une étiquette à une entrée basée sur un identifiant, ajoutez un commentaire « //@ » indiquant le nom de l’étiquette, 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 Linguist, les entrées basées sur des identifiants portant le même libellé sont regroupées, à l’instar des entrées textuelles qui sont regroupées par contexte. Tout élément sans libellé apparaît sous « <unnamed label> ».
Remarque : les nomsd’étiquettes n’ont aucun effet sur la recherche ou l’unicité : les ID restent globalement uniques et peuvent toujours être chargés via ` qtTrId("msgid") ` sans faire référence à une étiquette. La balise d’étiquette sert uniquement à faciliter la navigation du traducteur et ne modifie pas le comportement d’exécution.
Désambiguïser les textes identiques
Le système de traduction regroupe les chaînes de texte de l’interface utilisateur en éléments uniques afin d’éviter d’avoir à traduire plusieurs fois le même texte. Cependant, un texte peut sembler identique à un autre tout en ayant une signification différente. Par exemple, en anglais, « back » désigne à la fois un pas en arrière et la partie d’un objet opposée à l’avant. Vous devez signaler ces deux significations distinctes au système de traduction afin que le traducteur puisse créer deux traductions distinctes.
QML : ajouter un désambiguiseur à qsTr()
En QML, ajoutez une chaîne de désambiguïsation en tant que deuxième paramètre de la fonction qsTr().
Dans l’extrait de code suivant, l’ID « not front » permet de distinguer ce texte « Back » du texte « Back » correspondant à un pas en arrière :
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 élément de désambiguïsation à tr()
En C++, transmettez une chaîne de désambiguïsation lors de l’appel à tr().
Dans l’extrait de code suivant, l’ recipient d’ID permet de distinguer 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 afin de demander la séquence de touches spécifique à la plateforme associée à chaque raccourci.
Pour les raccourcis personnalisés, utilisez des chaînes lisibles par l’utilisateur, telles que Ctrl+Q ou Alt+F. Vous pouvez les traduire en raccourcis adaptés aux locuteurs de différentes langues.
Si vous codez en dur les raccourcis clavier dans votre application, les traducteurs ne pourront pas les remplacer.
Lorsque vous utilisez des raccourcis clavier dans le texte des éléments de menu et des boutons, un caractère mnémonique (souligné) indique qu’appuyer sur Alt ou Ctrl avec le caractère souligné effectue la même action que de cliquer sur l’élément de menu ou d’appuyer sur le bouton.
Par exemple, les applications utilisent souvent la lettre F comme caractère mnémonique dans le menu « File » ; vous pouvez donc 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 (« Fichier »), faites-lui précéder d’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++ : utilisation de 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 `.
Utilisez Locale pour étendre les fonctionnalités de localisation
Vous constaterez peut-être que certains graphismes ou éléments audio sont plus adaptés à certaines régions géographiques.
En règle générale, essayez d’éviter de localiser les images. Créez des icônes adaptées à l’échelle mondiale, plutôt que de vous appuyer sur des jeux de mots locaux ou des métaphores tirées par les cheveux. Cependant, vous devrez peut-être inverser les images des flèches pointant vers la gauche et vers la droite pour les paramètres régionaux arabes et hébreux.
« Locale » est l’un des sélecteurs de fichiers par défaut ; vous pouvez donc utiliser la sélection de fichiers pour afficher différentes images que vous fournissez en tant que ressources, en fonction des paramètres régionaux du système.
Les exemples de code QML et C++ présentés dans les sections suivantes partent du principe que vous fournissez 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.pngQML : définir la source d’une image
L'extrait de code QML suivant montre comment sélectionner une image source d'icône en fonction des paramètres régionaux actuels :
icon.source: "qrc:/images/language-icon.png"C++ : Utilisation de QFileSelector
L'extrait de code C++ suivant utilise ` QFileSelector ` pour choisir une icône de langue dans le dossier ` images ` en fonction des paramètres régionaux du système :
const QFileSelector selector;
const QIcon languageIcon(selector.select(":/images/language-icon.png"));Activer la traduction
Les noms de fichiers TS doivent contenir des codes de langue et de pays ISO :
- «language » 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 l’allemand comme langue cible, tandis que « qml_de_CH.ts » définit l’allemand comme langue cible et la Suisse comme pays cible. L’outil « lrelease » génère des fichiers QM nommés « qml_de.qm » et « qml_de_CH.qm », que l’application charge en fonction des paramètres régionaux du système.
QML : utiliser QQmlApplicationEngine
En QML, utilisez ` QQmlApplicationEngine ` pour charger automatiquement les fichiers de traduction à partir d'un sous-répertoire nommé ` i18n ` situé dans le répertoire contenant le fichier QML principal. Les noms des fichiers de traduction doivent comporter le préfixe ` qml_`. Par exemple, ` qml_en_US.qm`. Consultez les extraits de code CMake suivants pour savoir 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 de manière dynamique lorsque l'utilisateur clique sur le bouton :
Button {
anchors.centerIn: parent
text: qsTr("Translate")
onClicked: {
Qt.uiLanguage = Qt.uiLanguage === "en" ? "ja" : "en"
}
}C++ : Utilisation de 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++ se présente comme suit :
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 prenant en charge la traduction, vous créez un objet ` QTranslator `, vous ` load ez` une traduction en fonction des paramètres régionaux d’affichage de l’interface utilisateur de l’utilisateur au moment de l’exécution, puis vous intégrez l’objet traducteur dans l’application.
Préparation aux changements de langue dynamiques
Les fonctions ` Qt Widgets ` et ` Qt Quick ` utilisent toutes deux le système d’événements de Qt pour informer les classes des modifications de traduction.
LanguageChange Des événements sont déclenché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 niveau supérieur, puis, à partir de là, à l’ensemble de l’arborescence des widgets ou des types QML dérivés de Item.
Qt Widgets: Redéfinir changeEvent
Le gestionnaire d'événements par défaut des sous-classes de ` QWidget ` répond à l'événement ` QEvent::LanguageChange ` et appelle la fonction ` changeEvent() ` lorsque cela est nécessaire.
Pour que les widgets Qt prennent en compte les modifications apportées aux objets ` QTranslator ` installés, réimplémentez la fonction ` changeEvent()` du widget afin de 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 (UI) d’ Qt Widgets Designer (.ui) et la fonction 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 modification, appelez l’implémentation par défaut de la fonction.
La liste des traducteurs installés peut évoluer en réponse à un événement « LocaleChange », ou l’application peut proposer une interface utilisateur permettant à l’utilisateur de modifier la langue actuelle de l’application.
QML : redéfinition d’événement pour les types dérivés de `Item`
Pour les applications QML simples ne comportant aucun type C++ personnalisé enregistré, 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é d’ QQuickItem et que l’une de ses propriétés expose du texte traduit (ou dépend d’une autre manière de la langue), redéfinissez son ` event method ` et émettez le signal de changement de la propriété à l’intérieur (ou appelez ` notify ` dans le cas de propriétés liables). Par 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 dans le QML utilisant cette propriété sera réévaluée et tiendra compte du changement de langue.
Classes génériques dérivées de QObject : utilisation de filtres d’événements
Certaines classes ne dérivent ni de ` QWidget ` ni de ` QQuickItem`, mais peuvent néanmoins avoir besoin de gérer les événements de changement de langue. Dans ce cas, installez un filtre d’événement 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 seront ensuite affichées dans une interface utilisateur (par exemple, un item model personnalisé), ou lorsque la classe sert de conteneur de Widgets ou de Quick Items, et est donc chargée de leur transmettre l’événement.
Considérations supplémentaires concernant le code C++
Les sections suivantes contiennent des informations supplémentaires sur l’utilisation des classes et fonctions Qt C++ dans les applications traduisibles :
- Utilisez QString pour tout le texte visible par l’utilisateur
- Définir un contexte de traduction
- Traduire les classes non-Qt
- Traduire le texte situé en dehors d’une sous-classe de QObject
Utilisez QString pour tout le texte visible par l'utilisateur
QString utilise en interne le codage Unicode; vous pouvez donc utiliser des opérations de traitement de texte courantes pour traiter de manière transparente toutes les langues du monde. De plus, comme toutes les fonctions Qt qui affichent du texte à l'utilisateur prennent un objet ` QString ` en paramètre, il n'y a pas de surcharge liée à la conversion d'char * en QString.
Définir un contexte de traduction
Le contexte de traduction pour ` QObject ` et chacune de ses sous-classes ` QObject ` est le nom de la classe lui-même. Si vous créez une sous-classe de ` QObject`, utilisez la macro ` Q_OBJECT ` dans la définition de la classe pour redéfinir le contexte de traduction. Cette macro définit le contexte sur 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 la macro ` Q_OBJECT ` dans une définition de classe, le contexte est hérité de la classe de base. Par exemple, comme toutes les classes basées sur ` QObject` dans Qt fournissent un contexte, une nouvelle sous-classe de ` QWidget ` définie sans la macro ` Q_OBJECT ` utilise le contexte ` QWidget ` si vous appelez sa fonction ` tr() `.
Traduire les classes non-Qt
Vous devez fournir des informations supplémentaires à ` lupdate ` concernant les chaînes de caractères des classes qui n’héritent pas de ` QObject ` ou 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()`. Par exemple :
class MyClass
{
Q_DECLARE_TR_FUNCTIONS(MyClass)
public:
MyClass();
...
};Cela dote la classe de fonctions ` tr()` que vous pouvez utiliser pour traduire les chaînes associées à la classe, et permet à ` lupdate ` de détecter les chaînes traduisibles dans le code source.
Vous pouvez également appeler la fonction ` QCoreApplication::translate()` avec un contexte spécifique reconnu par ` lupdate ` et ` Qt Linguist `.
Traduire du texte situé en dehors d’une sous-classe de QObject
Si le texte entre guillemets ne se trouve pas dans une fonction membre d’une sous-classe de ` 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.