1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
|
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example localizedclock
\ingroup examples-linguist
\examplecategory {User Interface Components}
\meta tags {qtquick,i18n,l10n,linguist,plurals}
\title Localized Clock Example
\brief The example shows best practices for using Qt's translation and
localization features in CMake and Qt Quick including the handling
of plurals in different languages, and localized time and date formats.
See the \l{Qt Linguist Manual} for more information about
translating Qt applications.
\section1 User Interface
The example shows the current time and date in the locale and language of
your system. The texts in the UI are furthermore localized for
the following languages:
English, German, French, Spanish, Italian, Japanese, Korean, Portuguese,
Arabic, and Chinese.
If your desktop is in another language, it falls back to English.
To test different languages and locales without altering your system, the
example also accepts a locale as command line argument. For example,
starting localizedClock from the command line with the option
\c{--locale de} shows the clock in German, with a date and time
format as it is common in Germany.
The screenshot shows the en_US version:
\image linguist-localizedclock_en_US.webp {Screenshot of digital clock
in English (US)}
\section2 Internationalization
In the application translation is used to set the main window
title and a few UI texts, including ones with placeholders
and plural forms. The application counts the seconds with
\e{plural forms} enabled (see \l{Handle Plural Forms}). As a
result, depending on the count of seconds, the translation function
returns a different translation, with the correct grammatical
number for the target language.
For instance, in English, if the count is larger
than \e one, the \e plural form is used, otherwise the \e singular
form is used. In \l{Translation Rules for Plural Forms} you find
the plural rules for different languages.
The locale also affects how dates and times are displayed.
These are formatted according to the country conventions of the current
locale. For example, a German locale results in 24-hour time and
the day written before the month, while a US locale
uses a 12-hour clock, and the month is written before the day.
This screenshot shows the en_GB version. Notice that the data format is
different than the en_US version above, while the same English plural
translation is loaded in both cases.
\image linguist-localizedclock_en_GB.webp {Screenshot of digital clock
in English (UK)}
Here is the screenshot of the de_DE version, which similar to GB has a
different date format than US. Notice that the German translation for
regular and plural forms is loaded accordingly.
\image linguist-localizedclock_de_DE.webp {Screenshot of digital clock
in German}
\section1 Implementation
The implementation has three parts:
\list
\li \l{CMakeLists.txt}
\li \l{main.cpp}
\li \l{Main.qml}
\endlist
\section2 CMakeLists.txt
The CMake file of the application enables Qt's translation and localization support.
Here are the relevant pieces:
\c find_package(Qt6 REQUIRED COMPONENTS Core Linguist Qml Quick):
Finds and links the required Qt 6 modules, including \c Linguist which
are essential for internationalization.
\c qt_standard_project_setup(...):
Sets up the internationalization system with support for the listed
locales. \c I18N_SOURCE_LANGUAGE is left at its default value (English),
since the source code contains English texts.
\quotefromfile localizedclock/CMakeLists.txt
\skipto qt_standard_project_setup
\printuntil I18N_TRANSLATED_LANGUAGES
\c qt_add_translations(...):
Bundles the functionality of \c lupdate and \c lrelease by generating the
translation source files (TS files) in the "i18n" directory using
\c clock as the base name, and compiling them into binary \c .qm files if
they contain translations. The following TS files are generated:
\list
\li "clock_{de, ar, ko, zh, ja, fr, it, es, pt}.ts": One TS file per language
listed in \c I18N_TRANSLATED_LANGUAGES of \c qt_standard_project_setup
containing the translations to that language.
\li "clock_en.ts": Contains English plural forms, since the source code
has plural form translation ("%n second(s)").
The function \c qt_add_translations writes only the plural forms here,
as we specified the language of the texts in the source code as English,
by leaving \c I18N_SOURCE_LANGUAGE with the default value. So the reglular
texts do not need translations.
\endlist
\quotefromfile localizedclock/CMakeLists.txt
\skipto qt_add_translations
\printuntil )
\c qt_add_qml_module(...):
Adds a QML module under the URI \c qtexamples.localizedclock, including
the \l Main.qml file.
\quotefromfile localizedclock/CMakeLists.txt
\skipto qt_add_qml_module
\printuntil )
\section2 main.cpp
The starting point of the application. This part is responsible
for setting the locale, installing required translations, and
loading UI. Below is an explanation of the relevant pieces of code:
Define the locale argument, e.g., \c {--locale en_US} or \c{--locale de_DE}:
\quotefromfile localizedclock/main.cpp
\skipto QCommandLineParser parser
\printuntil parser.process
Parse the arguments, fetch the provided locale, and set the input
locale as the default locale of the application:
\quotefromfile localizedclock/main.cpp
\skipto QLocale locale
\printuntil QLocale::setDefault
Install the English translation regardless of the locale, to allow incomplete
translations for other languages. QTranslator queries translations
for texts in the reversed order the translations are installed:
\quotefromfile localizedclock/main.cpp
\skipto QTranslator enPlurals
\printuntil app.installTranslator
Install a translation according to the given locale. As English translation
is already installed in the previous step, we might end
up with two installed translations here. Qt uses the most recently installed
translation for any overlapping keys. Therefore, the locale-specific
translation will take precedence over English, and in case of any missing
translations, QTranslator falls back to English.
\quotefromfile localizedclock/main.cpp
\skipto QTranslator translation
\printuntil }
\printuntil }
\printuntil }
\section2 Main.qml
This QML file defines the main UI window of the application, which
presents time, date, the used locale, and a counter for seconds.
Below is an explanation of the relevant pieces of code:
\b {Set the title of the Window using qsTr() for translation.} To
find the translation for this text QTranslator queries in the
TS file of the current language the text \e{"Digital Clock"}
within the context \e{"Main"} (the file name):
\qml
title: qsTr("Digital Clock")
\endqml
\b{Show the number of seconds using qsTr() with plural (numeral) support.}
The plural form is enabled by using the special notation "%n"
(see \l{Handle Plural Forms}).
Depending on the value of n, the translation function returns a
different translation, with the correct grammatical number for the
target language.
For instance in English, if the value of \c root.seconds is larger
than one, the plural form is used, otherwise the singular form is used.
In \l{Translation Rules for Plural Forms} you find the plural rules
for different languages.
\qml
text: qsTr("%n second(s)", "seconds", root.seconds)
\endqml
\b{Display the current locale and use qsTr() to translate
the source text "Locale: %1".} Also the translation needs
to contain the argument notation "%1". As a result, the
argument of the text (i.e. \c{Qt.locale().name}) can
correctly be used to format the text:
\qml
text: qsTr("Locale: %1").arg(Qt.locale().name)
\endqml
\b{Format the time and date according to the locale convensions.}
Different countires might have specific preferences on
how time and date should be presented.
For instance, the German locale uses a 24-hour clock and writes
the day before the month, whereas the US locale follows a
12-hour clock and places the month before the day.
The method Date.toLocaleTimeString takes these considerations
into account and formats the time and date correctly based
on the given locale:
\quotefromfile localizedclock/Main.qml
\skipto const now
\printuntil root.date
*/
|