Sur cette page

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

L'exemple montre les meilleures pratiques pour utiliser les fonctionnalités de traduction basées sur l'ID de Qt dans CMake et Qt Quick, y compris la gestion des pluriels dans différentes langues et les formats d'heure localisés.

Interface utilisateur

L'exemple montre l'heure et la date actuelles dans la langue et les paramètres régionaux de votre système. La traduction des langues suivantes est prise en charge : anglais, allemand, français, espagnol, italien, japonais, coréen, portugais, arabe et chinois. Si votre bureau est dans une autre langue, il revient à l'anglais.

L'exemple accepte également une locale comme argument de ligne de commande pour tester différentes langues et locales sans modifier votre système : localizedClockIdBased --locale en_GB ou localizedClockIdBased --locale de

Par défaut, l'application affiche l'heure et la date dans la locale actuelle, mais elle propose également un bouton qui ouvre une boîte de dialogue avec une liste de 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). Cette approche permet de réutiliser les traductions dans différents contextes. Nous le démontrons en partageant une traduction entre Main.qml et le Time Zone Dialog, un formulaire basé sur QWidget écrit en C++. Un autre aspect de la traduction basée sur les ID est qu'elle sépare le texte affiché dans l'interface utilisateur des développeurs, ce qui rend le code source indépendant des mots réels présentés à l'utilisateur.

Dans les deux captures d'écran suivantes de l'application en anglais, les deux instances du texte "Select time zone : "dans la fenêtre principale (QML) et dans la boîte de dialogue (C++) partagent la même traduction en utilisant le même identifiant.

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

La boîte de dialogue avec une liste de fuseaux horaires (version anglaise) :

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

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

Mise en œuvre

L'application se compose de cinq parties :

CMakeLists.txt

Le fichier CMake de l'application active le support de traduction et de localisation basé sur l'ID de Qt. Voici les éléments pertinents :

find_package(Qt6 REQUIRED COMPONENTS Core Linguist Qml Quick): Trouve et lie les modules Qt 6 requis, y compris Linguist, essentiels pour l'internationalisation. qt_standard_project_setup(): Met en place le système d'internationalisation avec le support des locales listées. Bien que la langue source soit l'anglais, une traduction en anglais est toujours nécessaire lorsque l'on utilise 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 anglaise, de sorte que qt_add_translations crée un fichier TS pour l'anglais ; sinon, ils seront manquants au moment 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 sources de traduction (fichiers TS) dans le répertoire "i18n" en utilisant clock comme nom de base, et en les compilant en fichiers binaires .qm s'ils contiennent des traductions.

  • Génère un fichier TS par langue listée dans I18N_TRANSLATED_LANGUAGES de qt_standard_project_setup.
  • MERGE_QT_TRANSLATIONS et QT_TRANSLATION_CATALOGS qtbase incluent les traductions de Qt dans le projet. Ceci est nécessaire pour traduire les boutons du widget QDialog dans la boîte de dialogue du fuseau horaire. Comme le texte de ces boutons est contrôlé par QDialog, sans inclure les 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 ID-based Translation).
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 responsable de la définition des paramètres linguistiques, de l'installation des traductions requises et du chargement de l'interface utilisateur. Vous trouverez ci-dessous une explication des éléments de code pertinents :

Définir l'argument de la locale, 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);

Analyse les arguments, recherche la locale fournie et définit 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 anglaise indépendamment de la locale, pour permettre des traductions incomplètes dans d'autres langues. QTranslator interroge les traductions pour les textes dans l'ordre inverse de celui dans lequel les traductions sont installées :

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

Installe une traduction en fonction de la locale donnée :

    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 anglaise dans l'étape précédente, nous pourrions nous retrouver avec deux traductions installées. Qt utilise la traduction la plus récente pour toutes les clés qui se chevauchent. Par conséquent, la traduction locale sera prioritaire sur l'anglais et, en cas de traduction manquante, QTranslator reviendra à l'anglais.

Dialogue sur le fuseau horaire

Cette classe est une boîte de dialogue C++ basée sur QWidget(QDialog) qui affiche une boîte de dialogue QComboBox contenant une liste de fuseaux horaires. Vous trouverez ci-dessous une explication du code :

Activez la traduction basée sur l'ID 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'identifiant unique de la traduction :

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

Ajouter une étiquette avec une traduction basée sur l'ID (dialog.ui), avec l'ID "timezonelabel" :

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

Une classe QML_SINGLETON dans C++ responsable de la gestion des changements de fuseau horaire.

Lorsque l'utilisateur sélectionne un fuseau horaire, l'instance de TimeZoneManager se souvient du fuseau horaire choisi :

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

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

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

TimeZoneManager::currentTimeZoneOffsetMs() est marquée par Q_INVOKABLE et renvoie le décalage temporel du fuseau horaire sélectionné. Comme la classe TimeZoneManager est déclarée avec QML_ELEMENT et QML_SINGLETON, il est possible d'accéder directement à la méthode à partir de QML pour mettre à jour l'heure présenté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 utilisateur présente l'heure, la date, le fuseau horaire actuel et un compteur de secondes. Elle fournit également un bouton qui ouvre une boîte de dialogue permettant de modifier le fuseau horaire. Vous trouverez ci-dessous une explication des éléments de code pertinents :

Définir la fenêtre et définir son titre à l'aide de qsTrId() pour une traduction basée sur l'ID. Le texte de la langue source est spécifié à l'aide de la notation méta-chaîne //% (voir Traductions basées sur l'ID du texte). lupdate analyse les méta-chaînes et écrit les textes source 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 au moment de l'exécution. Par conséquent, lorsque l'application est chargée dans les paramètres linguistiques anglais, même si la langue source est l'anglais, elle doit installer la traduction anglaise pour présenter les textes anglais. Sinon, l'ID brut "Main-Digital-Clock" est affiché. C'est également la raison pour laquelle nous avons spécifié "en" dans I18N_TRANSLATED_LANGUAGES par la configuration dans CMakeLists.txt.

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

Afficher le nombre de secondes en utilisant qsTrId() avec le support du pluriel. Ici 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 chaîne méta (voir Gérer les 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 la forme singulière est utilisée. Dans Règles de traduction pour les formes plurielles, vous trouverez les règles du pluriel pour différentes langues.

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

Afficher le fuseau horaire sélectionné à l'aide d'une traduction basée sur l'ID, //% "Time zone: " spécifiant le texte dans la langue source :

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

Un bouton pour ouvrir la boîte de dialogue du 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 puisqu'il s'agit d'une réutilisation de l'identifiant "timezonelabel", qui était précédemment utilisé dans le document dialog.ui (voir Dialogues sur les fuseaux horaires). Dans la traduction basée sur les ID, il suffit de spécifier le texte source par ID une seule fois dans le projet :

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

Lors du changement de fuseau horaire et de la réception du signal TimeZoneManager::timeZoneChanged() (voir Gestionnaire de fuseaux horaires), mettre à 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 une minuterie qui se déclenche toutes les secondes et met à jour les propriétés de l'heure, de la date et des secondes. La minuterie 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();
        }
    }

La locale affecte l'affichage des dates et des heures. Celles-ci sont formatées en fonction des conventions nationales de la locale en cours. Par exemple, les paramètres régionaux allemands affichent l'heure sur 24 heures et le format de date DD.MM.YYYY, tandis que les paramètres régionaux américains affichent l'heure sur 12 heures et le format de date MM/DD/YYYY.

Exemple de projet @ 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.