이 페이지에서

ID 기반 번역으로 현지화된 시계

이 예제는 다른 언어의 복수형 처리와 현지화된 시간 형식을 포함하여 CMake와 Qt Quick 에서 Qt의 ID 기반 번역 기능을 사용하는 모범 사례를 보여줍니다.

사용자 인터페이스

이 예는 시스템의 로캘과 언어로 현재 시간과 날짜를 보여줍니다. 다음 언어에 대한 번역이 지원됩니다: 영어, 독일어, 프랑스어, 스페인어, 이탈리아어, 일본어, 한국어, 포르투갈어, 아랍어, 중국어. 데스크톱이 다른 언어로 되어 있으면 영어로 다시 표시됩니다.

이 예에서는 시스템을 변경하지 않고도 다양한 언어와 로캘을 테스트하기 위해 로캘을 명령줄 인수로 사용할 수도 있습니다. localizedClockIdBased --locale en_GB 또는 localizedClockIdBased --locale de

기본적으로 애플리케이션은 현재 로캘의 시간과 날짜를 표시하지만 시간대 목록이 있는 대화 상자를 여는 버튼도 제공합니다. 사용자는 이 대화 상자를 사용하여 시계의 표준 시간대를 변경할 수 있습니다.

ID 기반 번역

이 예에서는 번역 가능한 텍스트를 기존의 문맥 + 텍스트 조합이 아닌 고유 ID로 식별하는 ID 기반 번역을 사용합니다( 텍스트 ID 기반 번역 참조). 이 접근 방식을 사용하면 번역을 여러 컨텍스트에서 재사용할 수 있습니다. Main.qml과 C++로 작성된 QWidget 기반 양식인 표준 시간대 대화 상자 간의 번역을 공유하여 이를 시연합니다. ID 기반 번역의 또 다른 측면은 UI에 표시되는 텍스트와 개발자를 분리하여 사용자에게 표시되는 실제 단어와 소스 코드를 독립적으로 만든다는 점입니다.

다음 두 개의 영문 애플리케이션 스크린샷에서는 메인 창(QML)의 "시간대 선택." 텍스트의 두 가지 인스턴스를 볼 수 있습니다: " 텍스트의 기본 창(QML)과 대화 상자(C++)는 동일한 ID를 사용하여 동일한 번역을 공유합니다.

영어 버전의 애플리케이션 창 스크린샷:

시간대 목록이 있는 대화 상자(영어 버전):

독일어로 된 애플리케이션의 기본 창입니다:

표준 시간대 목록이 있는 대화 상자(독일어 버전):

구현

애플리케이션은 다섯 부분으로 구성되어 있습니다:

CMakeLists.txt

애플리케이션의 CMake 파일은 Qt의 ID 기반 번역 및 현지화 지원을 활성화합니다. 다음은 관련 부분입니다:

find_package(Qt6 REQUIRED COMPONENTS Core Linguist Qml Quick): 국제화에 필수적인 Linguist 를 포함하여 필요한 Qt 6 모듈을 찾아서 연결합니다. qt_standard_project_setup(): 나열된 로캘을 지원하는 국제화 시스템을 설정합니다. 소스 언어는 영어이지만 ID 기반 번역을 사용할 때는 여전히 영어 번역이 필요합니다. 소스 코드에는 ID만 포함되어 있고 소스 텍스트는 표시되지 않습니다. 따라서 영어 번역이 포함된 프로젝트를 설정하여 qt_add_translations가 영어용 TS 파일을 생성하도록 해야 하며, 그렇지 않으면 런타임에 누락될 수 있습니다.

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

qt_add_translations(...): clock 을 기본 이름으로 사용하여 "i18n" 디렉터리에 번역 소스 파일(TS 파일)을 생성하고 번역이 포함된 경우 바이너리 .qm 파일로 컴파일하여 lupdatelrelease 의 기능을 번들로 제공합니다.

  • qt_standard_project_setupI18N_TRANSLATED_LANGUAGES 에 나열된 언어당 하나의 TS 파일을 생성합니다.
  • MERGE_QT_TRANSLATIONSQT_TRANSLATION_CATALOGS qtbase 에는 프로젝트에 Qt 번역이 포함되어 있습니다. 이는 시간대 대화상자에서 QDialog 위젯의 버튼을 번역하는 데 필요합니다. 해당 버튼의 텍스트는 QDialog 에 의해 제어되므로 Qt 번역을 포함하지 않으면 해당 버튼이 번역되지 않습니다( ID 기반 번역의 독일어 스크린샷에서 대화 상자의 번역된 텍스트를 참조하세요).
qt_add_translations(localizedClockIdBased
    TS_FILE_BASE i18n/clock
    MERGE_QT_TRANSLATIONS
    QT_TRANSLATION_CATALOGS qtbase
    RESOURCE_PREFIX i18n
)

qt_add_qml_module(...): qtexamples.localizedclock , Main.qml 파일을 포함하고 표준 시간대 관리자의 소스 및 헤더 파일을 QML 모듈로 가져오는 URI 아래에 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

애플리케이션의 시작점입니다. 이 부분에서는 로캘 설정, 필요한 번역 설치 및 UI 로딩을 담당합니다. 다음은 관련 코드에 대한 설명입니다:

로캘 인수를 정의합니다(예: --locale en_US 또는 --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);

인수를 구문 분석하고 제공된 로캘을 가져온 다음 입력 로캘을 애플리케이션의 기본 로캘로 설정합니다:

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

로캘에 관계없이 영어 번역을 설치하여 다른 언어에 대한 불완전한 번역을 허용합니다. QTranslator 번역이 설치된 역순으로 텍스트에 대한 번역을 쿼리합니다:

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

지정된 로캘에 따라 번역기를 설치합니다:

    QTranslator translation; if (QLocale().language() != QLocale::영어) { 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()); } }

이전 단계에서 영어 번역을 설치했기 때문에 두 개의 번역이 설치되어 있을 수 있습니다. Qt는 겹치는 키에 대해 가장 최근에 설치된 번역을 사용합니다. 따라서 로케일별 번역이 영어보다 우선하며, 누락된 번역이 있는 경우 QTranslator 이 다시 영어가 됩니다.

시간대 대화 상자

이 클래스는 시간대 목록이 포함된 QComboBox 을 표시하는 C++ QWidget 기반 대화 상자(QDialog)입니다. 아래는 코드에 대한 설명입니다:

UI 양식(dialog.ui)에서 ID 기반 번역을 사용 설정합니다:

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

ID 기반 번역으로 제목을 설정합니다(dialog.ui). 여기서 '제목'은 번역의 고유 ID입니다:

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

ID 기반 번역(dialog.ui)으로 레이블을 추가하고, ID는 "timezonelabel"로 설정합니다:

<widget class="QLabel" name="label">
...
<property name="text">
<string id="timezonelabel">Select time zone</string>
</property>
...
</widget>
시간대 관리자

C++QML_SINGLETON 클래스가 시간대 변경 처리를 담당합니다.

사용자가 시간대를 선택하면 TimeZoneManager 인스턴스는 선택한 시간대를 기억합니다:

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

시간대를 업데이트하면 TimeZoneManager::timeZoneChanged 신호를 전송합니다:

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

TimeZoneManager::currentTimeZoneOffsetMs()Q_INVOKABLE 로 표시되며 선택한 시간대의 시간 오프셋을 반환합니다. TimeZoneManager 클래스는 QML_ELEMENTQML_SINGLETON으로 선언되므로 QML에서 이 메서드에 직접 액세스하여 제시된 시간을 업데이트할 수 있습니다( 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

메인 QML 파일은 애플리케이션의 사용자 인터페이스를 정의합니다. UI에는 시간, 날짜, 현재 표준 시간대, 초 카운터가 표시됩니다. 또한 시간대를 변경하기 위해 시간대 대화 상자를 여는 버튼도 제공합니다. 다음은 관련 코드에 대한 설명입니다:

ID 기반 번역의 경우 qsTrId()를 사용하여 창을 정의하고 제목을 설정합니다. 소스 언어의 텍스트는 메타 문자열 표기법 //% 을 사용하여 지정합니다( 텍스트 ID 기반 번역 참조). lupdate는 메타 문자열을 구문 분석하고 정의된 소스 텍스트를 TS 파일에 씁니다. 소스 텍스트는 메타 문자열을 사용하여 주석 형식으로 지정되므로 런타임에 애플리케이션에 표시되지 않습니다. 따라서 애플리케이션이 영어 로캘로 로드될 때 소스 언어가 영어이더라도 영어 텍스트를 표시하려면 영어 번역을 설치해야 합니다. 그렇지 않으면 원시 ID "Main-Digital-Clock"이 표시됩니다. 이것이 바로 CMakeLists.txt의 설정에서 I18N_TRANSLATED_LANGUAGES 에 "en"을 지정한 이유이기도 합니다.

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

복수를 지원하는 qsTrId()를 사용하여 초를 표시합니다. 여기서도 소스 언어의 텍스트는 //% 메타 문자열을 사용하여 지정됩니다. 복수형은 메타 문자열의 소스 텍스트에 특수 표기법 "%n"을 사용하여 사용할 수 있습니다(복수형 처리하기 참조). n의 값에 따라 번역 함수는 대상 언어에 맞는 올바른 문법 번호를 사용하여 다른 번역을 반환합니다. 예를 들어 영어의 경우 root.seconds 값이 1보다 크면 복수형이 사용되고, 그렇지 않으면 단수형이 사용됩니다. 복수형 번역 규칙에서 다양한 언어에 대한 복수형 번역 규칙을 확인할 수 있습니다.

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

ID 기반 번역을 사용하여 현재 선택된 시간대를 표시하며 //% "Time zone: " 은 소스 언어의 텍스트를 지정합니다:

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

표준 시간대 대화 상자를 여는 버튼입니다. 버튼의 텍스트는 ID 기반 번역의 경우 qsTrId()를 사용하여 지정됩니다. 이 경우 소스 텍스트는 더 이상 메타 문자열로 정의되지 않는데, 이는 이전에 dialog.ui 문서에서 사용되었던 ID "timezonelabel"을 재사용한 것이기 때문입니다(시간대 대화상자 참조). ID 기반 번역에서는 프로젝트에서 ID당 소스 텍스트를 한 번만 지정하면 충분합니다:

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

시간대를 변경하고 TimeZoneManager::timeZoneChanged() 신호를 수신하면(시간대 관리자 참조) diff 변수를 선택한 시간대의 시간 오프셋으로 업데이트합니다:

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

매초마다 트리거되고 시간, 날짜 및 초 속성을 업데이트하는 타이머를선언합니다. 타이머는 선택한 표준 시간대의 시간 오프셋에 현재 시간을 더하여 시간을 계산합니다:

    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();
        }
    }

로캘은 날짜와 시간이 표시되는 방식에 영향을 줍니다. 현재 로캘의 국가 규칙에 따라 형식이 지정됩니다. 예를 들어 독일 로캘은 24시간 시간과 DD.MM.YYYY 날짜 형식을 사용하지만 미국 로캘은 12시간 시계와 MM/DD/YYYYY 날짜 형식을 사용합니다.

예제 프로젝트 @ 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.