HowTo Translations (i18n)

April 28, 2016 — 6 Comments

Think international from the beginning

Even if you think, that you don’t need to support more then one language – it’s better to have this in mind from the beginning, because it’s hard to add later.

I’m developing business apps and business is international, so I’m always developing for multi-language support.

This article is a short summary what’s needed and covers configuration, translation and build process.

Configure Qt Creator External Tools

There’s an extra application Qt Linguist to translate and two important commands lupdate and lrelease. Using External Tools it’s easy to have access without leaving Qt Creator or the need of the command line. Here’s HowTo:

1. Configure easy access to Qt Linguist

Together with you Qt installation you got the Qt Linguist. Please take a look at the manual: http://doc.qt.io/qt-5/qtlinguist-index.html

qt_ling_manual

I’m living in Germany and always develop my APPs in english and immediately doing the translation to german. This way I always detect soon if I forgot to make a String translatable. (we’ll talk about this later) Also german words normaly need some more space so I can control how the app looks in german vs english. I already used the Qt Linguist for my BlackBerry 10 Cascades development and really like the tool.

You’ll find the Qt Linguist app here:

configure_creator_03

Thanks to tips I got from Qt community (creator list) I found out that you can open Qt Linguist directly from Qt Creator.

Preferences -> Environment –> External Tools is the key:

configure_creator_02

Fill out the description (Linguist) and path to the Executable (Tap Choose and Select Linguist)

It’s a good idea to set the Working Directory. Instead of a hardcoded path you can also use a variable: %{CurrentProject:Path} Now the Linguist always opens inside your current project.

Adding the External Tool will place it under ‘Uncategorized’ – move it via Drag-n-Drop under existing Linguist category.

Now it’s easy to start the Linguist from inside your Qt Creator:

qt-linguist-logo

configure_creator_05

From Linguist open the files to translate (.ts).

A first screenshot from Linguist so you’ll get the idea:

configure_creator_06

As I opened Qt Linguist first time, I got it in german. Unfortunately there’s no language settings as described for Qt Creator above.

This little trick does it:

configure_creator_07

Search the translation files for linguist and rename the linguist_de.qm file – now Linguist opens in english.

(I created a Feature Request: https://bugreports.qt.io/browse/QTBUG-52456)

2. Configure lupdate in External Tools

Under Preferences –> Environment –> External Tools there already exist access to commands for lupdate and lrelease. (lupdate is looking for the strings you marked as translatable and to create or update the translation files <app>.ts. Using Linguist or external tools you can then translate the strings. lrelease compiles these translations from *.ts into *.qm. Only *.qml files will be deployed to your device)

I found out that the default configuration doesn’t work on Android and iOS – please change the executable:

06_qtc_ext_tools_04

3. Configure lrelease in External Tools

Do the same for lrelease:

06_qtc_ext_tools_05

That’s all to configure.

Make your Strings translatable

You can read in detail about this in Qt documentation:

Here’s a short starter:

To enable your app to use a Translator you have to add some lines of code into your main.cpp:

#include <QTranslator>
    // ...
    QGuiApplication app(argc, argv);

    QTranslator translator;
    if (translator.load(QLocale(), QLatin1String("my_app"), QLatin1String("_"), QLatin1String(":/translations"))) {
        app.installTranslator(&translator);
    } else {
        qDebug() << "cannot load translator " << QLocale::system().name() << " check content of translations.qrc";
    }

    QQmlApplicationEngine engine;
	// ...

Translation in your C++ sources is done using tr(), in QML files using qsTr()

QML: (simple text to be translated)

Label {
    text: qsTr("City")
}

QML: (text with arguments)

Label {
	property int theValue: 42
	text: qsTr("The answer of all is %1").arg(theValue)
}

QML: (text with arguments and quantity)

Label {
	property int count: 1
	text: qsTr("%1 piece(s)","",count).arg(count)
}

That’s all you need to know for your sourcecode.

HowTo extract translatable Strings

Now as your C++ and QML code contains all the stuff to make your Strings translatable – HowTo get these Strings out of your code to be able to translate using Qt Linguist or other solutions ?

lupdate does this. If you followed my tips above, you can use lupdate from External Tools inside Qt Creator. At first lupdate must know the languages used and also where to find the C++ and QML sources. Here are the relevant parts from my_app.pro:

TARGET = my_app
# cpp sources
SOURCES += main.cpp
# qml sources
lupdate_only {
    SOURCES +=  main.qml \
    common/*.qml \
    demo/*.qml
}
# Supported languages
LANGUAGES = de en fr
# used to create .ts files
 defineReplace(prependAll) {
     for(a,$$1):result += $$2$${a}$$3
     return($$result)
 }
 # Available translations
 tsroot = $$join(TARGET,,,.ts)
 tstarget = $$join(TARGET,,,_)
 TRANSLATIONS = $$PWD/translations/$$tsroot
 TRANSLATIONS += $$prependAll(LANGUAGES, $$PWD/translations/$$tstarget, .ts)

The compiler needs all C++ sources, lupdate also needs the qml sources. Using lupdate_only {} does the trick not to confuse the compiler. To avoid the need to create .ts files for each language the $$prependAll – stuff does this:

  • create my_app.ts
  • create my_app_de.ts
  • create my_app_en.ts
  • create my_app_fr.ts

All files are created inside project working dir at /translations – so this directory should be there.

Translate your Strings

Now open Qt Linguist from External Tools and select the .ts files.

Attention: Never open the rootfile my_app.ts – this file will always be regenerated from lupdate !.

Build and Run your APP on Android or iOS Devices

The compiled APP won’t use the *.ts files – the APPs always need the compressed compiled version *.qm.

lrelease compiles your .ts files into .qm files. Here’s the part for this in your my_app.pro:

# run LRELEASE to generate the qm files
qtPrepareTool(LRELEASE, lrelease)
 for(tsfile, TRANSLATIONS) {
     command = $$LRELEASE $$tsfile
     system($$command)|error("Failed to run: $$command")
 }

This will create the *.qm files where your *.ts files are: at root of your project dir in /translations folder.

If you take a look at the code in your main.cpp (see above) where QTranslater was loaded using :/translations as path to my_app_xx.qm files, you know from :/ that *.qm files must be part of Qt Resources.

For this from my_app.pro we’re providing a .qrc file containing all the qm files:

RESOURCES += qml.qrc \
    translations.qrc

Unfortunately the .qm files won’t automatically become part of translations.qrc. You have to add them manually. This only must be done if adding new languages. In this case you have to at the language to LANGUAGES in .pro, then run lupdate and build your project to create the new .ts and .qm files. Then you can right-click on translations.qrc and use Add Existing Files to add the .qm for the new language.

That’s it🙂

Summary

I spent much time to figure this out and to find a way without use of command line. Hopefully I described it in a way to make it easy for you to start translations in your Android and iOS APPs.

Here are the most important workflows HowTo translate your text and HowTo add more supported languages.

(The app from the screenshots below is named ‘one_page_x’)

Workflow adding / editing translatable Strings

workflow_text_edited

Workflow supporting a new language

workflow_new_language

Cascades does it different

Doing x-platform apps also for BlackBerry 10 (C++/Qt 4.8/Cascades) it’s really easy:

Only add the languages to your project file (bar-descriptor.xml) …

cascades_add

… then build the project and all the lupdate/lrelease ts/qm stuff is done by magic under the hood:

cascades_ts_qm


← Back (Qt Creator – First Deployment)

→ Next Article (HowTo survive as a Qt Newbie)

⇐ Home (Overview / Topics)

6 responses to HowTo Translations (i18n)

  1. 

    A better executable path for linguist (stolen from lupdate and lrelease settings) would probably be:

    %{CurrentProject:QT_INSTALL_BINS}/linguist

    Also, another useful thing might be to define some shortcuts for these tools, if you’re using them often enough with Preferences > Environment > Keyboard.

  2. 

    How can i add all my ts-files as Arguments to open them with linguist via the external tool configuration? I mean the Variable above “Working Directory” where i insert “%{CurrentProject:Path}”. in the field “Arguments” i want something like that “%{CurrentProject:Translations}” so that all ts-files which are added in my *.pro-file will be opened directly, too. “%{CurrentProject:Translations}” did not work🙂

    • 

      it’s better to post such questions at creator list where the Qt Creator devs are listening. If you haven’t subscribed: http://lists.qt-project.org/mailman/listinfo/qt-creator

      • 

        i got ananswer but i don’t get it working:

        Executable: bash
        Args: -c ‘”%{CurrentProject:QT_INSTALL_BINS}/linguist” “%{CurrentProject:Path}/*.ts”’

        i tried to port it wo Windows, so my code looks like:
        Executable: C:\Windows\System32cmd.exe
        Args: /c %{CurrentProject:QT_INSTALL_BINS}/linguist %{CurrentProject:Path}/*.ts

        But did not work. Unknow TS Files Message.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s