Sur cette page

Horloge localisée avec traduction basée sur l'identifiant

Cet exemple présente les bonnes pratiques pour utiliser les fonctionnalités de traduction basées sur les identifiants de Qt dans CMake et Qt Quick, notamment la gestion des pluriels dans différentes langues et la localisation des formats d'heure.

Interface utilisateur

Cet exemple affiche l'heure et la date actuelles selon les paramètres régionaux et la langue de votre système. La traduction est prise en charge dans les langues suivantes : anglais, allemand, français, espagnol, italien, japonais, coréen, portugais, arabe et chinois. Si votre bureau est configuré dans une autre langue, l'affichage se fait par défaut en anglais.

L'exemple accepte également une paramétrage régional en tant qu'argument de ligne de commande pour tester différentes langues et paramétrages régionaux sans modifier votre système : localizedClockIdBased --locale en_GB ou localizedClockIdBased --locale de

Par défaut, l'application affiche l'heure et la date selon les paramètres régionaux actuels, mais elle propose également un bouton qui ouvre une boîte de dialogue contenant une liste des fuseaux horaires. L'utilisateur peut utiliser cette boîte de dialogue pour modifier le fuseau horaire de l'horloge.

Traduction basée sur l'ID

Dans cet exemple, nous utilisons la traduction basée sur les identifiants, où les textes traduisibles sont identifiés par un identifiant unique plutôt que par la combinaison traditionnelle « contexte + texte » (voir Traductions basées sur les identifiants de texte). Cette approche permet de réutiliser les traductions dans différents contextes. Nous illustrons cela en partageant une traduction entre Main.qml et la boîte de dialogue « Time Zone », un formulaire basé sur l’ QWidget et écrit en C++. Un autre aspect de la traduction basée sur les identifiants est qu’elle sépare le texte affiché dans l’interface utilisateur de celui des développeurs, rendant ainsi le code source indépendant des mots réellement présentés à l’utilisateur.

Dans les deux captures d’écran suivantes de l’application en anglais, les deux occurrences du texte « Select time zone: » dans la fenêtre principale (QML) et dans la boîte de dialogue (C++) partagent la même traduction grâce à l’utilisation du même identifiant.

Capture d’écran de la fenêtre de l’application en version anglaise :

La boîte de dialogue contenant la liste des fuseaux horaires (version anglaise) :

La fenêtre principale de l'application en allemand :

La boîte de dialogue contenant la liste des fuseaux horaires (version allemande) :

Mise en œuvre

L'application comporte cinq parties :

CMakeLists.txt

Le fichier CMake de l'application active la prise en charge de la traduction et de la localisation basée sur les identifiants (ID) de Qt. Voici les extraits pertinents :

find_package(Qt6 REQUIRED COMPONENTS Core Linguist Qml Quick): Recherche et lie les modules Qt 6 requis, notamment Linguist, indispensables à l’internationalisation. qt_standard_project_setup(): Configure le système d’internationalisation avec la prise en charge des paramètres régionaux répertoriés. Bien que la langue source soit l’anglais, une traduction en anglais reste nécessaire lors de l’utilisation de la traduction basée sur les ID. Le code source ne contient que les identifiants et ne voit pas les textes sources. Par conséquent, nous devons configurer le projet avec la traduction en anglais, afin que `qt_add_translations` crée un fichier TS pour l’anglais ; sinon, ceux-ci seront manquants lors de l’exécution.

qt_standard_project_setup(REQUIRES 6.8
    I18N_TRANSLATED_LANGUAGES de ar ko zh ja fr it es pt en)

qt_add_translations(...): Regroupe les fonctionnalités de lupdate et lrelease en générant les fichiers source de traduction (fichiers TS) dans le répertoire « i18n » en utilisant clock comme nom de base, puis en les compilant en fichiers binaires .qm s’ils contiennent des traductions.

  • Génère un fichier TS par langue répertoriée dans I18N_TRANSLATED_LANGUAGES de qt_standard_project_setup.
  • MERGE_QT_TRANSLATIONS et QT_TRANSLATION_CATALOGS qtbase permettent d’inclure les traductions Qt dans le projet. Cela est nécessaire pour traduire les boutons du widget QDialog dans la boîte de dialogue « Fuseau horaire ». Le texte de ces boutons étant géré par QDialog, sans l’inclusion des traductions Qt, ces boutons ne sont pas traduits (voir les textes traduits de la boîte de dialogue dans les captures d’écran en allemand dans la section « Traduction basée sur l’ID »).
qt_add_translations(localizedClockIdBased
    TS_FILE_BASE i18n/clock
    MERGE_QT_TRANSLATIONS
    QT_TRANSLATION_CATALOGS qtbase
    RESOURCE_PREFIX i18n
)

qt_add_qml_module(...): Ajoute un module QML sous l’URI qtexamples.localizedclock, inclut le fichier Main.qml et importe les fichiers source et d’en-tête de Time Zone Manager dans le module QML.

qt_add_qml_module(localizedClockIdBased
    URI qtexamples.localizedclock
    VERSION 1.0
    QML_FILES
        Main.qml
    RESOURCES dialog.ui
    SOURCES
        timezonemanager.h timezonemanager.cpp
        dialog.h dialog.cpp
)
main.cpp

Point de départ de l'application. Cette partie est chargée de définir les paramètres régionaux, d'installer les traductions requises et de charger l'interface utilisateur. Vous trouverez ci-dessous une explication des éléments de code pertinents :

Définissez l’argument de paramètres régionaux, par exemple --locale en_US ou --locale de_DE:

    QCommandLineParser parser;
    QCommandLineOption localeOption("locale"_L1, "Locale to be used in the user interface"_L1,
                                    "locale"_L1);
    parser.addOption(localeOption);
    parser.addHelpOption();
    parser.process(app);

Analyser les arguments, récupérer la locale fournie et définir la locale d'entrée comme locale par défaut de l'application :

        QLocale locale(parser.value(localeOption));
        qInfo() << "Setting locale to" << locale.name();
        QLocale::setDefault(locale);

Installe la traduction en anglais quelle que soit la locale, afin de permettre des traductions incomplètes pour les autres langues. QTranslator recherche les traductions des textes dans l'ordre inverse de celui dans lequel elles ont été installées :

    QTranslator enPlurals;
    const auto enPluralsPath = ":/i18n/clock_en.qm"_L1;
    if (!enPlurals.load(enPluralsPath))
        qFatal("Could not load %s!", qUtf8Printable(enPluralsPath));
    app.installTranslator(&enPlurals) ;

Installer une traduction en fonction des paramètres régionaux indiqués :

    QTranslator translation;
    if (QLocale().language() != QLocale::English) {
        if (translation.load(QLocale(), "clock"_L1, "_"_L1, ":/i18n/"_L1)) {
            qInfo("Loading translation %s",
                  qUtf8Printable(QDir::toNativeSeparators(translation.filePath())));
            if (!app.installTranslator(&translation))
                qWarning("Could not install %s!",
                         qUtf8Printable(QDir::toNativeSeparators(translation.filePath())));
        } else {
            qInfo("Could not load translation to %s. Using English.",
                  qUtf8Printable(QLocale().name()));
        }
    }

Comme nous avons installé la traduction en anglais à l’étape précédente, il se peut que nous nous retrouvions avec deux traductions installées. Qt utilise la traduction installée le plus récemment pour toutes les clés qui se chevauchent. Par conséquent, la traduction spécifique à la locale aura la priorité sur celle en anglais, et en cas de traductions manquantes, QTranslator se rabattra sur l’anglais.

Boîte de dialogue « Fuseau horaire »

Cette classe est une boîte de dialogue C++ basée sur QWidget(QDialog) qui affiche une « QComboBox » contenant une liste de fuseaux horaires. Voici une explication du code :

Activer la traduction basée sur les identifiants dans le formulaire de l'interface utilisateur (dialog.ui) :

<ui version="4.0" idbasedtr="true">

Définir le titre avec une traduction basée sur l'ID (dialog.ui). Ici, « title » est l'ID unique de la traduction :

<property name="windowTitle">
    <string id="title">Time Zone</string>
</property>

Ajoutez une étiquette avec une traduction basée sur l’ID (dialog.ui), dont l’ID est « timezonelabel » :

<widget class="QLabel" name="label">
...
<property name="text">
<string id="timezonelabel">Select time zone</string>
</property>
...
</widget>
Gestionnaire de fuseaux horaires

Une classe de type « QML_SINGLETON » dans C++ chargée de gérer les changements de fuseau horaire.

Lorsque l’utilisateur sélectionne un fuseau horaire, l’instance de ` TimeZoneManager ` mémorise le fuseau horaire choisi :

        connect(m_dialog.get(), &Dialog::timeZoneSelected, this, &TimeZoneManager::setTimeZone);

La mise à jour du fuseau horaire déclenche un signal TimeZoneManager::timeZoneChanged :

        connect(m_dialog.get(), &Dialog::timeZoneSelected, this, &TimeZoneManager::setTimeZone);
    }
    m_dialog->show();
}

TimeZoneManager::currentTimeZoneOffsetMs() est marquée d’un « Q_INVOKABLE » et renvoie le décalage horaire du fuseau horaire sélectionné. La classe « TimeZoneManager » étant déclarée avec « QML_ELEMENT » et « QML_SINGLETON », la méthode est directement accessible depuis QML pour mettre à jour l’heure affichée ; voir également Main.qml.

qint64 TimeZoneManager::currentTimeZoneOffsetMs()
{
    const QTimeZone tz(m_timeZone.toLatin1());
    if (!tz.isValid())
        return 0;
    const QDateTime nowUtc = QDateTime::currentDateTimeUtc();

    const int targetOffset = tz.offsetFromUtc(nowUtc);
    const int systemOffset = QTimeZone::systemTimeZone().offsetFromUtc(nowUtc);

    return (targetOffset - systemOffset) * 1000;
}
Main.qml

Le fichier QML principal définit l’interface utilisateur de l’application. L’interface affiche l’heure, la date, le fuseau horaire actuel et un compteur de secondes. Elle comporte également un bouton qui ouvre une boîte de dialogue « Fuseau horaire » permettant de modifier le fuseau horaire. Vous trouverez ci-dessous une explication des parties de code pertinentes :

Définissez la fenêtre et configurez son titre à l’aide de ` qsTrId()` pour une traduction basée sur les identifiants. Le texte de la langue source est spécifié à l’aide de la notation de méta-chaîne //% (voir Traductions basées sur les identifiants de texte). lupdate analyse les méta-chaînes et écrit les textes sources définis dans le fichier TS. Comme le texte source est spécifié à l’aide de méta-chaînes et sous la forme d’un commentaire, il n’est pas visible par l’application lors de l’exécution. Par conséquent, lorsque l’application est chargée avec les paramètres régionaux anglais, même si la langue source est l’anglais, elle doit tout de même installer la traduction anglaise pour afficher les textes en anglais. Sinon, l’ID brut « Main-Digital-Clock » s’affiche. C’est également la raison pour laquelle nous avons spécifié « en » dans I18N_TRANSLATED_LANGUAGES via la configuration dans CMakeLists.txt.

//% "Digital Clock"
title: qsTrId("Main-Digital-Clock")

Afficher le nombre de secondes à l’aide de qsTrId() avec prise en charge du pluriel. Là encore, le texte dans la langue source est spécifié à l’aide de la méta-chaîne //%. La forme plurielle est activée en utilisant la notation spéciale « %n » dans le texte source de la méta-chaîne (voir Gestion des formes plurielles). 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. Par exemple, en anglais, si la valeur de root.seconds est supérieure à un, la forme plurielle est utilisée ; sinon, c’est la forme singulière qui est utilisée. Vous trouverez les règles relatives au pluriel pour différentes langues dans la section « Règles de traduction pour les formes plurielles ».

//% "%n second(s)"
text: qsTrId("Main-n-second-s", root.seconds)

Affichez le fuseau horaire actuellement sélectionné à l’aide d’une traduction basée sur un identifiant, l’ //% "Time zone: " e spécifiant le texte dans la langue source :

//% "Time zone: "
text: qsTrId("timezone") + TimeZoneManager.timeZone;

Un bouton permettant d’ouvrir la boîte de dialogue « Fuseau horaire ». Le texte du bouton est spécifié à l’aide de qsTrId() pour la traduction basée sur les identifiants. Dans ce cas, le texte source n’est plus défini par des méta-chaînes, car il s’agit d’une réutilisation de l’identifiant « timezonelabel », qui avait déjà été utilisé dans le document dialog.ui (voir Boîte de dialogue « Fuseau horaire »). Dans la traduction basée sur les identifiants, il suffit de spécifier le texte source par identifiant une seule fois dans le projet :

        Button {
            text: qsTrId("timezonelabel")
            onClicked: TimeZoneManager.openDialog()
            Layout.alignment: Qt.AlignHCenter
        }

Lors du changement de fuseau horaire et à la réception du signal ` TimeZoneManager::timeZoneChanged() ` (voir Gestionnaire de fuseaux horaires), mettez à jour la variable ` diff ` avec le décalage horaire du fuseau horaire sélectionné :

    Connections {
        target: TimeZoneManager
        function onTimeZoneChanged() {
            root.diff = TimeZoneManager.currentTimeZoneOffsetMs();
        }
    }

Déclarez un minuteur qui se déclenche toutes les secondes et met à jour les propriétés « heure », « date » et « secondes ». Le minuteur calcule l'heure en ajoutant l'heure actuelle au décalage horaire du fuseau horaire sélectionné :

    Timer {
        interval: 1000
        running: true
        repeat: true
        triggeredOnStart: true

        onTriggered: {
            const now = new Date(new Date().getTime() + root.diff);
            const locale = Qt.locale();
            root.time = now.toLocaleTimeString(locale, Locale.ShortFormat);
            root.date = now.toLocaleDateString(locale);
            root.seconds = now.getSeconds();
        }
    }

Les paramètres régionaux influencent l’affichage des dates et des heures. Celles-ci sont formatées selon les conventions en vigueur dans le pays correspondant aux paramètres régionaux actuels. Par exemple, les paramètres régionaux allemands utilisent le format horaire de 24 heures et le format de date JJ.MM.AAAA, tandis que les paramètres régionaux américains utilisent le format horaire de 12 heures et le format de date MM/JJ/AAAA.

Exemple de projet sur code.qt.io

© 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.