IDベース翻訳によるローカライズド・クロック
この例では、CMake とQt Quick で Qt の ID ベースの翻訳機能を使用する際のベストプラクティスを示します。異なる言語での複数形の扱いや、ローカライズされた時刻フォーマットも含まれます。
ユーザーインターフェース
この例では、システムのロケールと言語で現在の時刻と日付を表示しています。以下の言語の翻訳がサポートされています:英語、ドイツ語、フランス語、スペイン語、イタリア語、日本語、韓国語、ポルトガル語、アラビア語、中国語。デスクトップが他の言語で表示されている場合は、英語にフォールバックされます。
この例では、システムを変更せずに異なる言語やロケールをテストするために、コマンドライン引数としてロケールを指定することもできます。localizedClockIdBased --locale en_GB またはlocalizedClockIdBased --locale de
デフォルトでは、アプリケーションは現在のロケールで時刻と日付を表示しますが、タイムゾーンのリストを表示するダイアログを開くボタンも用意されています。ユーザーはこのダイアログを使って、時計のタイムゾーンを変更することができます。
IDベースの翻訳
この例では、IDベースの翻訳を使用しています。翻訳可能なテキストは、従来のコンテキストとテキストの組み合わせではなく、一意のIDによって識別されます(テキストIDベースの翻訳を参照)。このアプローチにより、異なるコンテキスト間で翻訳を再利用することができます。Main.qmlとC++で書かれたQWidget-based formであるTime Zone Dialogの間で翻訳を共有することで、これを実証します。IDベースの翻訳のもう一つの側面は、UIに表示されるテキストを開発者から分離し、ソースコードをユーザーに表示される実際の言葉から独立させることです。
以下の2つのスクリーンショットは英語版のアプリケーションですが、メインウィンドウ(QML)の "Select time zone:"の2つのインスタンスは、メインウィンドウ(QML)とダイアログ(C++)で同じIDを使用することにより、同じ翻訳を共有しています。
英語版アプリケーションのスクリーンショット:

タイムゾーンのリストを表示するダイアログ(英語版):

アプリケーションのメインウィンドウ(ドイツ語版

タイムゾーン一覧ダイアログ(ドイツ語版):

実装
このアプリケーションには5つの部分があります:
CMakeリスト.txt
アプリケーションのCMakeファイルは、QtのIDベースの翻訳とローカリゼーションのサポートを有効にします。以下に関連する部分を示します:
find_package(Qt6 REQUIRED COMPONENTS Core Linguist Qml Quick): Linguistqt_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 ファイルにコンパイルすることで、lupdate とlrelease の機能をバンドルします。
qt_standard_project_setupのI18N_TRANSLATED_LANGUAGESにリストされている言語ごとに 1 つの TS ファイルを生成します。MERGE_QT_TRANSLATIONSそして、QT_TRANSLATION_CATALOGS qtbaseQt の翻訳をプロジェクトに含めます。これはタイムゾーンダイアログのQDialogウィジェットのボタンを翻訳するために必要です。これらのボタンのテキストはQDialog によって制御されているため、Qt 翻訳を含めないと、これらのボタンは翻訳されません(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(...): qtexamples.localizedclock という URI の下に 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ロケール(parser.value(localeOption)); qInfo() << "Setting locale to" << locale.name(); QLocale::setDefault(locale);
ロケールに関係なく英語翻訳をインストールし、他の言語の不完全な翻訳を許可します。QTranslator 翻訳がインストールされる順序を逆にして、テキストの翻訳を問い合わせます:
QTranslatorenPlurals;const autoenPluralsPath= ":/i18n/clock_en.qm"_L1;if(!enPlurals.load(enPluralsPath)) qFatal("Could not load %s!", qUtf8Printable(enPluralsPath)); app.installTranslator(&enPlurals);
指定されたロケールに従った翻訳をインストールします:
QTranslator翻訳;if(QLocale().language()!=QLocale::English) {if(翻訳.ロード(QLocale(), "clock"_L1, "_"_L1, ":/i18n/"_L1)) { { { { ().language() ! 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()); } }
前のステップで英語の翻訳をインストールしたので、2つの翻訳がインストールされるかもしれません。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 から直接アクセスして、表示されている時刻を更新することができます。
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;タイムゾーンダイアログを開くためのボタン。ボタンのテキストは、qsTrId() を使ってIDベース翻訳で指定されます。この場合、以前dialog.uiドキュメントで使われていたID "timezonelabel"(タイムゾーンダイアログ参照)を再利用しているため、ソーステキストはメタ文字列で定義されていません。IDベースの翻訳では、IDごとにソーステキストを指定するのはプロジェクト内で1回だけで十分です:
Button { text: qsTrId("timezonelabel") onClicked: TimeZoneManager.openDialog() Layout.alignment: Qt.AlignHCenter }
タイムゾーンを変更し、TimeZoneManager::timeZoneChanged() シグナルを受信したら(タイムゾーンマネージャーを参照)、diff 変数を選択したタイムゾーンのタイムオフセットで更新します:
Connections { target: TimeZoneManager function onTimeZoneChanged() { root.diff = TimeZoneManager.currentTimeZoneOffsetMs(); } }
1秒ごとにトリガーし、時刻、日付、秒のプロパティを更新するタイマーを宣言する。タイマーは、現在時刻に選択されたタイムゾーンの時刻オフセットを加算して時刻を計算する:
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.