ID 기반 변환 기능이 적용된 지역별 시계
이 예제는 CMake 및 Qt Quick 에서 Qt의 ID 기반 번역 기능을 사용하는 모범 사례를 보여줍니다. 여기에는 다양한 언어의 복수형 처리 및 지역화된 시간 형식 등이 포함됩니다.
사용자 인터페이스
이 예제는 시스템의 로케일 및 언어로 표시된 현재 시간과 날짜를 보여줍니다. 영어, 독일어, 프랑스어, 스페인어, 이탈리아어, 일본어, 한국어, 포르투갈어, 아랍어, 중국어에 대한 번역이 지원됩니다. 데스크톱이 다른 언어로 설정된 경우 영어로 대체됩니다.
또한 이 예제는 시스템 설정을 변경하지 않고도 다양한 언어와 로케일을 테스트할 수 있도록 명령줄 인수로 로케일을 지정할 수 있습니다. 예: localizedClockIdBased --locale en_GB 또는 localizedClockIdBased --locale de
기본적으로 이 애플리케이션은 현재 로캘의 시간과 날짜를 표시하지만, 시간대 목록이 포함된 대화 상자를 여는 버튼도 제공합니다. 사용자는 이 대화 상자를 통해 시계의 시간대를 변경할 수 있습니다.
ID 기반 번역
이 예제에서는 ID 기반 번역을 사용합니다. 이 방식에서는 번역 가능한 텍스트를 기존의 ‘문맥 + 텍스트’ 조합 대신 고유한 ID로 식별합니다( ‘텍스트 ID 기반 번역’ 참조). 이 접근 방식을 사용하면 서로 다른 문맥에서 번역을 재사용할 수 있습니다. 이를 시연하기 위해 Main.qml과 C++로 작성된 ‘ QWidget ’ 기반 양식인 ‘시간대 대화상자’ 간에 번역을 공유합니다. ID 기반 번역의 또 다른 장점은 UI에 표시되는 텍스트를 개발자 코드와 분리함으로써, 소스 코드가 사용자에게 실제로 표시되는 단어와 독립적으로 유지된다는 점입니다.
다음은 영어로 된 애플리케이션의 스크린샷 두 장으로, 메인 창(QML)과 대화 상자(C++)에 각각 표시된 “Select time zone: ”이라는 텍스트는 동일한 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(...): ` lupdate ` 및 ` lrelease `의 기능을 통합하여, ` clock `을 기본 이름으로 하여 "i18n" 디렉터리에 번역 소스 파일(TS 파일)을 생성하고, 번역 내용이 포함된 경우 이를 바이너리 .qm 파일로 컴파일합니다.
qt_standard_project_setup의I18N_TRANSLATED_LANGUAGES에 나열된 언어별로 TS 파일을 하나씩 생성합니다.MERGE_QT_TRANSLATIONS그리고QT_TRANSLATION_CATALOGS qtbase는 프로젝트에 Qt 번역을 포함합니다. 이는 시간대 대화 상자( Time Zone Dialog) 내QDialog위젯의 버튼을 번역하는 데 필요합니다. 해당 버튼의 텍스트는 QDialog 에 의해 제어되므로, Qt 번역을 포함하지 않으면 해당 버튼은 번역되지 않습니다( ID 기반 번역( 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(...): URI qtexamples.localizedclock 아래에 QML 모듈을 추가하고, Main.qml 파일을 포함하며, Time Zone Manager의 소스 파일과 헤더 파일을 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::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()));
}
}이전 단계에서 영어 번역을 설치했기 때문에, 총 두 개의 번역이 설치된 상태가 될 수 있습니다. Qt는 중복되는 키에 대해서는 가장 최근에 설치된 번역을 사용합니다. 따라서 로케일별 번역이 영어 번역보다 우선 적용되며, 번역이 누락된 경우 QTranslator 는 영어로 대체됩니다.
시간대 대화 상자
이 클래스는 C++ QWidget 기반 대화 상자(QDialog)로, 시간대 목록이 포함된 QComboBox 을 표시합니다. 다음은 코드에 대한 설명입니다:
UI 양식(dialog.ui)에서 ID 기반 변환을 활성화합니다:
<ui version="4.0" idbasedtr="true">ID 기반 번역을 사용하여 제목을 설정합니다(dialog.ui). 여기서 "title"은 번역의 고유 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_ELEMENT QML_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는 시간, 날짜, 현재 시간대 및 초 카운터를 표시합니다. 또한 시간대를 변경하기 위한 ‘시간대 대화 상자’를 여는 버튼도 제공합니다. 다음은 관련 코드 부분에 대한 설명입니다:
qsTrId()를 사용하여 ID 기반 번역을 통해 창을 정의하고 제목을 설정합니다. 원본 언어의 텍스트는 메타 문자열 표기법 //% 을 사용하여 지정됩니다( ‘텍스트 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/YYYY 날짜 형식이 사용됩니다.
© 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.