En esta página

Reloj localizado con traducción basada en ID

El ejemplo muestra las mejores prácticas para usar las características de traducción basadas en ID de Qt en CMake y Qt Quick, incluyendo el manejo de plurales en diferentes idiomas y formatos de hora localizados.

Interfaz de usuario

El ejemplo muestra la hora y la fecha actuales en la configuración regional y el idioma de su sistema. Se admite la traducción a estos idiomas: Inglés, alemán, francés, español, italiano, japonés, coreano, portugués, árabe y chino. Si tu escritorio está en otro idioma, vuelve al inglés.

El ejemplo también acepta una configuración regional como argumento de línea de comandos para probar diferentes idiomas y configuraciones regionales sin alterar el sistema.: localizedClockIdBased --locale en_GB o localizedClockIdBased --locale de

Por defecto, la aplicación muestra la hora y la fecha en la configuración regional actual, pero también proporciona un botón que abre un diálogo con una lista de zonas horarias. El usuario puede utilizar el diálogo para cambiar la zona horaria del reloj.

Traducción basada en ID

En este ejemplo, utilizamos la traducción basada en ID, en la que los textos traducibles se identifican mediante un ID único en lugar de la combinación tradicional contexto + texto (véase Traducciones basadas en ID de texto). Este método permite reutilizar las traducciones en distintos contextos. Lo demostramos compartiendo una traducción entre Main.qml y el diálogo de zona horaria, un formulario basado en QWidget escrito en C++. Otro aspecto de la traducción basada en ID es que separa el texto mostrado en la interfaz de usuario de los desarrolladores, haciendo que el código fuente sea independiente de las palabras reales presentadas al usuario.

En las dos capturas de pantalla siguientes de la aplicación en inglés, las dos instancias del texto "Select time zone: " en la ventana principal (QML) y en el cuadro de diálogo (C++) comparten la misma traducción al utilizar el mismo ID.

Captura de pantalla de la ventana de la aplicación en versión inglesa:

El diálogo con la lista de zonas horarias (versión inglesa):

La ventana principal de la aplicación en alemán:

El diálogo con la lista de husos horarios (versión en alemán):

Aplicación

La aplicación consta de cinco partes:

CMakeLists.txt

El archivo CMake de la aplicación habilita el soporte de traducción y localización basado en ID de Qt. Aquí están las piezas relevantes:

find_package(Qt6 REQUIRED COMPONENTS Core Linguist Qml Quick): Encuentra y enlaza los módulos Qt 6 necesarios, incluyendo Linguist, esencial para la internacionalización. qt_standard_project_setup(): Configura el sistema de internacionalización con soporte para las localizaciones listadas. Aunque el idioma de origen es el inglés, sigue siendo necesaria una traducción al inglés cuando se utiliza la traducción basada en ID. El código fuente sólo contiene los IDs y no ve los textos fuente. Por lo tanto, tenemos que configurar el proyecto con la traducción Inglés, de modo que qt_add_translations crea un archivo TS para Inglés, de lo contrario, se perderán en tiempo de ejecución.

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

qt_add_translations(...): Agrupa la funcionalidad de lupdate y lrelease generando los archivos fuente de traducción (archivos TS) en el directorio "i18n" utilizando clock como nombre base, y compilándolos en archivos binarios .qm si contienen traducciones.

  • Genera un archivo TS por cada idioma listado en I18N_TRANSLATED_LANGUAGES de qt_standard_project_setup.
  • MERGE_QT_TRANSLATIONS y QT_TRANSLATION_CATALOGS qtbase incluye las traducciones de Qt en el proyecto. Esto es necesario para traducir los botones del widget QDialog en el Diálogo de Zona Horaria. Como el texto de esos botones está controlado por QDialog, sin incluir las traducciones de Qt esos botones no se traducen (ver los textos traducidos del diálogo en las capturas de pantalla en alemán en Traducción basada en ID).
qt_add_translations(localizedClockIdBased
    TS_FILE_BASE i18n/clock
    MERGE_QT_TRANSLATIONS
    QT_TRANSLATION_CATALOGS qtbase
    RESOURCE_PREFIX i18n
)

qt_add_qml_module(...): Añade un módulo QML bajo el URI qtexamples.localizedclock, incluye el archivo Main.qml, e importa los archivos fuente y de cabecera del Gestor de Zonas Horarias al módulo 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

El punto de partida de la aplicación. Esta parte es responsable de establecer la configuración regional, instalar las traducciones necesarias y cargar la interfaz de usuario. A continuación se explican los fragmentos de código relevantes:

Defina el argumento de configuración regional, por ejemplo, --locale en_US o --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);

Analiza los argumentos, busca la configuración regional proporcionada y establece la configuración regional de entrada como la configuración regional predeterminada de la aplicación:

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

Instala la traducción al inglés independientemente de la configuración regional, para permitir traducciones incompletas para otros idiomas. QTranslator consulta las traducciones de los textos en el orden inverso en que se instalan las traducciones:

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

Instala una traducción según la configuración regional dada:

    QTranslator translation; if (QLocale().language() != QLocale::Español) { if (translation.load(QLocale(), "reloj"_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())); } }

Como instalamos la traducción al inglés en el paso anterior, podríamos terminar con dos traducciones instaladas. Qt utiliza la traducción instalada más recientemente para cualquier clave superpuesta. Por lo tanto, la traducción específica de la localización tendrá prioridad sobre la inglesa, y en caso de que falte alguna traducción, QTranslator volverá a la inglesa.

Diálogo de zona horaria

Esta clase es un diálogo basado en C++ QWidget(QDialog) que muestra un QComboBox que contiene una lista de zonas horarias. A continuación se explica el código:

Habilite la traducción basada en ID en el formulario UI (dialog.ui):

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

Establecer el título con traducción basada en ID (dialog.ui). Aquí, "title" es el ID único de la traducción:

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

Añade una etiqueta con traducción basada en ID (dialog.ui), con el ID "timezonelabel":

<widget class="QLabel" name="label">
...
<property name="text">
<string id="timezonelabel">Select time zone</string>
</property>
...
</widget>
Gestor de zonas horarias

Una clase QML_SINGLETON en C++ responsable de gestionar los cambios de zona horaria.

Cuando el usuario selecciona una zona horaria, la instancia de TimeZoneManager recuerda la zona horaria elegida:

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

La actualización de la zona horaria emite una señal TimeZoneManager::timeZoneChanged:

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

TimeZoneManager::currentTimeZoneOffsetMs() está marcada con Q_INVOKABLE y devuelve el desfase horario de la zona horaria seleccionada. Dado que la clase TimeZoneManager se declara con QML_ELEMENT y QML_SINGLETON, se puede acceder directamente al método desde QML para actualizar la hora presentada; véase también 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

El archivo QML principal define la interfaz de usuario de la aplicación. La interfaz de usuario presenta la hora, la fecha, la zona horaria actual y un contador de segundos. También proporciona un botón que abre un Diálogo de Zona Horaria para cambiar la zona horaria. A continuación se explican los fragmentos de código relevantes:

Definir la ventana y establecer su título utilizando qsTrId() para la traducción basada en ID. El texto para el idioma de origen se especifica utilizando la notación meta string //% (véase Traducciones basadas en ID de texto). lupdate analiza las meta strings y escribe los textos de origen definidos en el archivo TS. Como el texto fuente se especifica utilizando meta strings y en forma de comentario, no son visibles para la aplicación en tiempo de ejecución. Por lo tanto, cuando la aplicación se carga en la configuración regional inglesa, aunque el idioma de origen esté en inglés, sigue siendo necesario instalar la traducción al inglés para presentar los textos en inglés. De lo contrario, se mostrará el ID en bruto "Main-Digital-Clock". Esta es también la razón por la que especificamos "en" en I18N_TRANSLATED_LANGUAGES por la configuración en CMakeLists.txt.

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

Mostrar el número de segundos usando qsTrId() con soporte plural. De nuevo aquí el texto en el idioma fuente se especifica usando la meta cadena //%. La forma plural se habilita usando la notación especial "%n" en el texto fuente en la meta cadena (ver Manejar formas plurales). Dependiendo del valor de n, la función de traducción devuelve una traducción diferente, con el número gramatical correcto para el idioma de destino. Por ejemplo, en inglés, si el valor de root.seconds es mayor que uno, se utiliza la forma plural; en caso contrario, se utiliza la forma singular. En Reglas de traducción para formas plurales encontrará las reglas de plural para distintos idiomas.

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

Mostrar la zona horaria actualmente seleccionada utilizando la traducción basada en ID, con //% "Time zone: " especificando el texto en el idioma de origen:

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

Un botón para abrir el diálogo de zona horaria. El texto del botón se especifica utilizando qsTrId() para la traducción basada en ID. En este caso, el texto de origen ya no se define mediante meta strings, ya que se trata de una reutilización del ID "timezonelabel", que se utilizó anteriormente en el documento dialog.ui (véase Diálogo de zona horaria). En la traducción basada en ID, basta con especificar el texto fuente por ID una sola vez en el proyecto:

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

Al cambiar la zona horaria y recibir la señal TimeZoneManager::timeZoneChanged() (véase Gestor de zona horaria), actualice la variable diff con el desfase horario de la zona horaria seleccionada:

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

Declara un temporizador que se active cada segundo y actualice las propiedades de hora, fecha y segundos. El temporizador calcula la hora sumando la hora actual al desfase horario de la zona horaria seleccionada:

    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 configuración regional afecta al modo en que se muestran las fechas y las horas. Éstas se formatean de acuerdo con las convenciones del país de la configuración regional actual. Por ejemplo, una configuración regional alemana da como resultado una hora de 24 horas y un formato de fecha DD.MM.AAAA, mientras que una configuración regional estadounidense utiliza un reloj de 12 horas y un formato de fecha MM/DD/AAAA.

Proyecto de ejemplo @ 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.