translating qt applications
DESCRIPTION
Supporting several languages is a key point to increase the audience of an application. We will see what is needed in Qt to enable internationalization and how to ensure all the components can be translated. We will also see the tools available for the translators and how to use them. Presentation by Benjamin Poulain held during Qt Developer Days 2009. http://qt.nokia.com/developer/learning/elearningTRANSCRIPT
![Page 1: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/1.jpg)
09/12/09
Translating Qt applicationsIt does not have to be boring ;-)
![Page 2: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/2.jpg)
Who is Benjamin Poulain at Nokia?
2
• first support engineer
– Linux and Mac OS X
• now Webkit developer
• pet projects
– graphical tablet
– Cocoa support
![Page 3: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/3.jpg)
What do I do after work?
• some hacking
– web applications
• lots of sport: running, cycling, climbing
I am not so good on a snowboard
![Page 4: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/4.jpg)
Why do I work on translations?
• my family do not speak english
➡need for localized software
• work on
– tutorial in french
– translation of Qt Creator
– french community of Qt
![Page 5: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/5.jpg)
What are we gonna do today?
• Why bother?
• Translating your application
• Tools for translators
• Going further
• Conclusion
![Page 6: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/6.jpg)
What are we gonna do today?
• Why bother?
• Translating your application
• Tools for translators
• Going further
• Conclusion
![Page 7: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/7.jpg)
Translations increase your user base
Everybody speaks English. right?
Do not understand English
Secondary
Native speaker
writing an application is difficult ➜ spread it
![Page 8: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/8.jpg)
What are we gonna do today?
• Why bother?• Translating your application
– Simple application– UI– Source– Integrate the translation
• Tools for translators• Going further• Conclusion
![Page 9: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/9.jpg)
Ugly Snake is a mini game in Qt
![Page 10: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/10.jpg)
How do we translate the application?
1) write code ready for translation
2) extract strings
3) translate
4) compile strings
Internationalization workflow:
![Page 11: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/11.jpg)
What are we gonna do today?
• Why bother?• Translating your application
– Simple application– UI– Source– Integrate the translation
• Tools for translators• Going further• Conclusion
![Page 12: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/12.jpg)
The .ui files are the biggest part
• most strings are in the .ui
• this is what is seen by the user
• good news: work out of the box
- string extraction
- translation
![Page 13: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/13.jpg)
What are we gonna do today?
• Why bother?• Translating your application
– Simple application– UI– Source– Integrate the translation
• Tools for translators• Going further• Conclusion
![Page 14: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/14.jpg)
Translate the strings with tr()
• QObject::tr() translate a string:trayIcon.showMessage("new message", "you have too many mail");
• works great with QString::arg():
tr("%n user(s) online").arg(userCount);
QString::number(userCount) + "users online";
trayIcon.showMessage(tr("new message"), tr("you have too many mail"));
![Page 15: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/15.jpg)
Provide some context for short strings
tr("The %1 is %2").arg(...);What are 1, 2?
![Page 16: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/16.jpg)
Provide some context for short strings
3 ways to add context:
– luck
– context in tr():
– comment in code
tr("The %1 is %2").arg(...);What are 1, 2?
tr("The %1 is %2", "The <extension> is <state>").arg(...);
//: The <extension> is <state>tr("The %1 is %2").arg(...);
![Page 17: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/17.jpg)
How to mark strings for translations?
• tr() returns QString
• QT_TR_NOOP marks for translation
• translated later with tr()
char *const EDITOR = QT_TR_NOOP("emacs");
void function() { (...) QString editor = tr(EDITOR); (...)}
example:
![Page 18: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/18.jpg)
What are we gonna do today?
• Why bother?• Translating your application
– Simple application– UI– Source– Integrate the translation
• Tools for translators• Going further• Conclusion
![Page 19: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/19.jpg)
Applications use a compiled version of the translation
• lrelease compiles .ts in .qm
• .qm is the binary format for release
• fast lookup
• not into the binary
![Page 20: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/20.jpg)
A translator must be installed
• QTranslator
- translate the strings
- load the .qm file:
QTranslator uglySnakeTranslator;uglySnakeTranslator.load("uglysnake_" + QLocale::system().name(), QCoreApplication::applicationDirPath());app.installTranslator(&uglySnakeTranslator);
![Page 21: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/21.jpg)
What are we gonna do today?
• Why bother?
• Translating your application
• Tools for translators
• Going further
• Conclusion
![Page 22: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/22.jpg)
There are two kinds of tools for translators
• offline ➜ Qt Linguist
• online ➜ Pootle, ...
![Page 23: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/23.jpg)
Presentation of Linguist
![Page 24: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/24.jpg)
Linguist is great but need to be distributed
• support multiple languages (simultaneously)
• great integration with Qt
• integration with the UI files:
• errors are spoted imediately
• full context
but: need to be distributed
![Page 25: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/25.jpg)
Presentation of Pootle
![Page 26: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/26.jpg)
Pootle is great, but offer no integration
• no need to distribute
• easier for amateur
but: no integration (ui files!)
![Page 27: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/27.jpg)
What are we gonna do today?
• Why bother?• Translating your application• Tools for translators• Going further
– “context”– tricky UI– change the language– pitfalls
• Conclusion
![Page 28: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/28.jpg)
One word, multiple concepts
edit
édition
éditer
noun
verb
tr("edit", "verb");tr("edit", "noun");
• short text ➜ context
• also in designer
![Page 29: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/29.jpg)
Comments does not disambiguate the strings
QString a = tr("edit", "N97");QString b = tr("edit", "N900");
• works:
• do not work//: N97QString a = tr("edit");
//: N900QString b = tr("edit");
• why?
![Page 30: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/30.jpg)
Understanding context and disambiguation
QPushButton::tr("edit", "verb");
context
disambiguation
QCoreApplication::translate("QPushButton", "edit", "verb");
QTranslator::translate("QPushButton", "edit", "verb");
context source disambiguation ➜ result
QPushButton edit verb ➜ editer
QPushButton edit ➜
source
![Page 31: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/31.jpg)
Comments does not disambiguate the strings
QString a = tr("edit", "N97");QString b = tr("edit", "N900");
• works:
• do not work://: N97QString a = tr("edit");
//: N900QString b = tr("edit");
• solution://: N97QString a = tr("edit", "phoneA");
//: N900QString b = tr("edit", "phoneB");
![Page 32: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/32.jpg)
What are we gonna do today?
• Why bother?• Translating your application• Tools for translators• Going further
– “context”– tricky UI– change the language– pitfalls
• Conclusion
![Page 33: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/33.jpg)
The translation should fit the widgets
• the layouts adapt the widgets
• problems:
- fixed size- phone screen
![Page 34: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/34.jpg)
Some images need a translation
• localize icons, images, etc
• qresource support locale:
<qresource lang="fr"> <file>burnIcon.png</file></qresource>
![Page 35: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/35.jpg)
What if you want multiple UI?
• cultural conventions
• phone screens
• right to left interface
✓ Solution: QUiLoader to load the UI
X difficult to maintain
X difficult to document
![Page 36: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/36.jpg)
What are we gonna do today?
• Why bother?• Translating your application• Tools for translators• Going further
– “context”– tricky UI– change the language– pitfalls
• Conclusion
![Page 37: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/37.jpg)
What if the language is changed after the start?
• examples:
- phone
- public terminal
- MS Windows applications
![Page 38: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/38.jpg)
Everything needs a new translation
• LanguageChange event on ::installTranslator()
• QWidget::changeEvent() to catch the event
• UI responds to retranslateUI()
• manual update for the code
void SettingsPanel::changeEvent(QEvent *e){ if (e->type() == QEvent::LanguageChange) { ui->retranslateUi(this); updateSpeedDescription(); } QWidget::changeEvent(e);}
![Page 39: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/39.jpg)
When to change the translators?
• LocaleChange event to the active window
➡ install event filter on QApplication
➡ change the translators
![Page 40: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/40.jpg)
What are we gonna do today?
• Why bother?• Translating your application• Tools for translators• Going further
– “context”– tricky UI– change the language– pitfalls
• Conclusion
![Page 41: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/41.jpg)
Translate on painting is not a good strategy
char languageList[] = { QT_TR_NOOP("english"), QT_TR_NOOP("german") };
if (language == "english”) { ...
void paintEvent(QEvent *) { QString toShow = tr(m_language); ...}
list sorted alphabetically:
✓ Solution: use classes for identity, not strings
![Page 42: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/42.jpg)
The source might not be in Latin 1
• tr() uses Latin 1 by default
✓ Solution 1: use English for the source
✓ Solution 2:
- QTextCodec::setCodecForTr()
- CODECFORTR = UTF-8
tr("Qt est génial"); // might fail
![Page 43: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/43.jpg)
Mac uses an ordered list of language
• Mac OS X
- ordered list of languages
• language selection:QTranslator uglySnakeTranslator;uglySnakeTranslator.load("uglysnake_" + QLocale::system().name(), QCoreApplication::applicationDirPath());app.installTranslator(&uglySnakeTranslator);
Not accurate
✓ Solution: iterate over the languages of core foundation
![Page 44: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/44.jpg)
What are we gonna do today?
• Why bother?
• Translating your application
• Tools for translators
• Going further
• Conclusion
![Page 45: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/45.jpg)
Qt makes translation easy
• Internationalization is important
• Qt already solves the problems
• Minimal changes are needed in the code
– tr() every string
– provide context for short strings
➡ think about it when you develop
![Page 46: Translating Qt Applications](https://reader034.vdocuments.mx/reader034/viewer/2022052321/5551d84eb4c90501638b4598/html5/thumbnails/46.jpg)