The text ID translation mechanism is an industrial strength system for internationalization and localization. Each text in the application has a unique identifier (text ID) that you use in the source code instead of text. This makes it much easier to manage large numbers of translated texts.
注意: You must use only plain-text-based or only text-ID-based functions in one application. If you mix them, you will end up with an incomplete set of texts to be translated.
When using text IDs instead of plain text, the general method of internationalizing an application is the same but the details are a bit different:
qsTrId()
function instead of qsTr(), the
QT_TRID_NOOP()
macro instead of
QT_TR_NOOP
(),和
QT_TRID_N_NOOP()
macro instead of
QT_TR_N_NOOP
()).
qsTrId("id-back-not-front")
qsTrId("id-back-backstep")
differentiates the back-step
Back
从
id-back-not-front
Back
.
//%
comment. If you do not include this, the text ID is shown in the user interface. This is especially important when you have texts with parameters. The
//%
comment needs to include the parameters indicators in the string. For example,
//% "Number of files: %1"
//:
comments that provide extra information to the translator are optional in the plain-text system. However, with the text-ID-based system, this extra information becomes essential because without it you only have the text ID and the translator might not be able to make a sensible translation from that without further context. You can use long descriptive text IDs and no comments, but comments are often easier to understand.
The side-by-side code snippets below show a comparison of text-ID -based and plain-text-based translations:
基于文本 ID | 基于纯文本 |
---|---|
Text { id: backTxt; //: The back of the object, not the front //% "Back" //~ Context Not related to back-stepping text: qsTrId("id-back-not-front"); } |
Text { id: backTxt; //: The back of the object, not the front //~ Context Not related to back-stepping text: qsTr("Back","Not front") } |
Localizing with text IDs follows much the same process as for plain text.
You use the lupdate tool to generate the TS files where you add the translations. The source values in the translation files will be text IDs rather than plain text, and therefore you need either descriptive text IDs or good additional comments, or both to ensure that the translations are accurate.
The example text-ID-based user interface text from above results in the following content in the .ts file:
<message id="id-back-not-front"> <source>Back</source> <extracomment>The back of the object, not the front</extracomment> <translation type="unfinished"></translation> <extra-Context>Not related to back-stepping</extra-Context> </message>
当使用
lrelease
, you need to specify that the keys for translated texts are based on text IDs, rather than plain text. If you use
qsTr()
to mark the strings as translatable in the code, the
id
attribute is not set and
lrelease
ignores them.
However, if there is no translation available for a given text (which is generally the case until late in development), the text ID will be shown in the user interface rather than a proper text. In order to make the application more usable for testing, you can make
lrelease
使用
Engineering English
source text (from the
//%
comments) as the translated text and mark it with some indicator, such as an exclamation mark (!), so you can see texts that are not yet translated.
When building with CMake, use the prefix
qml_
for .ts files. For example,
qml_en.ts
. In the CMakeLists.txt file, add the
qt_add_translations
function, where you list the *.ts files as values of
TS_FILES
, set the value of RESOURCE_PREFIX to the URI of the main.qml file for the project followed by /i18n, and set the value of
LRELEASE_OPTIONS
to
-idbased
:
qt_add_translations(${CMAKE_PROJECT_NAME} TS_FILES i18n/qml_de_DE.ts i18n/qml_en_US.ts RESOURCE_PREFIX Main/i18n LRELEASE_OPTIONS -idbased )
For projects that target a large number of locales, you can remove the TRANSLATIONS info from the .pro file and, instead, manage the translations with a separate script. The script can call
lrelease
and
lupdate
for each of the desired targets.
The updates could be scripted something like this:
lupdate -recursive <project-dir> -ts <project-dir>/i18n/myapp-text_en_GB.ts lupdate -recursive <project-dir> -ts <project-dir>/i18n/myapp-text_en_US.ts ...
The generation of the final .qm files could be scripted something like this:
lrelease -idbased <project-dir>/i18n/myapp-text_en_GB.ts lrelease -idbased <project-dir>/i18n/myapp-text_en_US.ts ...