Internationalization of software is the process of allowing the software to be used efficiently by all people of the world. This means adapting to user and locality preferences such as language, input techniques, character encodings, and presentation conventions.
Writing cross-platform international software with Qt is a gentle, incremental process. Your software can become internationalized in the following stages:
Since QString uses the Unicode encoding internally, all the languages of the world can be processed transparently using familiar text processing operations. Also, since all Qt functions that present text to the user take a QString as a parameter, there is no char* to QString conversion time.
Strings that are in "programmer space" - such as QObject names and file format texts need not use QString - the traditional char*, or the QCString class will suffice.
You're unlikely to notice that you are using unicode - QString, and QChar are just like easier versions of the clumsy const char* and char from traditional C.
Where your program uses "quoted text" for text that will be presented to the user, ensure it goes through the QApplication::translate() function, usually this simply means using tr(). For example, assuming LoginWidget is a subclass of QWidget:
LoginWidget::LoginWidget() { QLabel *label = new QLabel( tr("Password:"), this ); ... }
This is 99% of the strings you're likely to write.
If the quoted text is not in a member function of a QObject/QWidget subclass, use either the tr() function of an approriate class, or the QApplication::translate() function directly:
void some_global_function(LoginWidget* logwid) { QLabel *label = new QLabel( LoginWidget::tr("Password:"), logwid ); } void same_global_function(LoginWidget* logwid) { QLabel *label = new QLabel( qApp->translate("LoginWidget", "Password:"), logwid ); }
Finally, if you need to have translatable text completely outside a funciton, there are two macros to help: QT_TR_NOOP() and QT_TRANSLATE_NOOP(). They merely mark the text for extraction by the findtr utility described below - the macros expand to just the text (without the scope). Example usages are shown below.
QString FriendlyConversation::greeting(int greet_type) { static const char* greeting_strings[] = { QT_TR_NOOP("Hello"), QT_TR_NOOP("Goodbye") }; return tr(greeting_strings[greet_type]); } static const char* greeting_strings[] = { QT_TRANSLATE_NOOP("FriendlyConversation","Hello"), QT_TRANSLATE_NOOP("FriendlyConversation","Goodbye") }; QString FriendlyConversation::greeting(int greet_type) { return tr(greeting_strings[greet_type]); }
If you disable the const char* to QString automatic conversion by compiling your software with the macro QT_NO_CAST_ASCII defined, you'll be very likely to catch any strings you are missing. See QString::fromLatin1() for more details. Disabling the conversion can make programming cumbersome.
The printf() style of inserting arguments in strings is a poor choice for internationalized text, as it is sometimes necessary to change the order of arguments when translating. The QString::arg() functions offer a simple means for substituting arguments:
void FileCopier::showProgress(int done, int total, const QString& current_file ) { label.setText( tr("%1 of %2 files copied.\nCopying: %3") .arg(done) .arg(total) .arg(current_file) ); }
Once you are using tr() sufficiently, you can start producing translations of the user-visible text in your program.
Provided with Qt are three utility programs that assist in the management of translations:
findtr *.cpp *.h >myapp.po copy myapp.po myapp_de.po edit myapp_de.po
msg2qm myapp_de.po myapp_de.qm msg2qm myapp_fr.po myapp_fr.qm msg2qm myapp_ja.po myapp_ja.qm
In your application, use QTranslator::load() to load translation files appropriate for the user's language.
mergetr myapp_de.po myapp.po mergetr myapp_fr.po myapp.po mergetr myapp_ja.po myapp.po
The translation team then edits the new .po files to translate the new or changed texts. When texts change, the old text is included in the .po file as a comment to guide the new translation (no "fuzzy" matching is done).
Note that Qt itself contains a small number of strings that will
also need to be translated to the languages which you are targetting.
In the near future Qt will ship with translations for some languages.
We recommend that if you need to translate the Qt strings now
that you put the translations in separate .po and .qm files. This
will simplify transition to the official Qt translations. To create
a .po file for all Qt sources:
\code
findtr qt/src/
Copyright © 1999 Troll Tech Trademarks