Qt/C++ - Lesson 049. QTranslator - dynamic translation of multilingual application to Qt

Qt, Linguist, QTranslator

Sooner or later, the developer of Qt applications meets the need multilanguage support of  his application. Then you can to use QTranslator class and Qt Linguist for creating of translations.

QTranslator object class is used to load translation from a special file with the extension .qm, which is a hexadecimal file of translations. This file is compiled from the translation file in XML format, which has the extension .ts and it is prescribed in the project profile. This file contains all of the application line, which were concluded in the tr() function. I recommend describe the entire interface of the application in English, which will be the default language, and translations have to load the desired language from the translation files. If the required translation file is not found, it will automatically be downloaded in English translation. Although you can certainly use another language as the default language.

Translation download Example

The structure of the file name of the translation has an important role in working with QTranslator . Let us see the minimum example.

#include "mainwindow.h"
#include <QApplication>
#include <QTranslator>
#include <QLibraryInfo>

int main(int argc, char *argv[])
    QApplication a(argc, argv);

    QTranslator qtLanguageTranslator;
    qtLanguageTranslator.load(QString("QtLanguage_") + QString("ru_RU"));

    MainWindow w;

    return a.exec();

In this example creates a class object QTranslator, in which we will download the file , which is interested for us, indicating the language. In this case, the full name of the file translation following QtLanguage_ru.qm. That is, given the general name for the file transfer QtLanguage, as well as language translation prefix _ru. But you may have noticed that as an argument for using load generated QtLanguage_ru_RU line. This is done in order to determine the proper dialect, such as the US (en_US) or British (en_GB) English. But if in the translation file name is not specified dialect, then the file will be selected without specifying a dialect, for example, QtLanguage_ru.qm.

After the translations file is downloaded, it must be installed in the application. In this case, it uses a global pointer to the application qApp->installTranslator (&qtLanguageTranslator).

Creating a translation file

Once we figured out a way to transfer the minimum settings in the application, let's understand, how do you can create a translation. To create a translation is necessary to use the following functions: tr(), trUtf8 (), translate () in the application, etc. That is, all the text that will require translation is necessary to frame it in those functions, then to create a translation file. Look it might read:

label->setText(QApplication::translate("MainWindow", "Select Language", 0));
label_3->setText(trUtf8("Hello world"));

Once in the application marked all the necessary lines, you will need to create a translation file, do the translation itself directly and compile the final translation file. To do this, use the following programs:

  1. lupdate - program for the formation of the field of translation TRANSLATIONS pro file in the file and update information on all new lines in applications that require translation.
  2. lrelease - program for the compile of the final translation file to be used in the application.
  3. Qt Linguist - directly the package itself to create translations.

The first step that needs to be done after the application has registered a string requiring translation is to add the file to be translated into pro project file. You may also want to specify the encoding information that is used for the translation.

TRANSLATIONS += QtLanguage_ru.ts


Next, you need to use a utility to create lupdate QtLanguage_ru.ts file. In Qt Creator, look here: Tools -> External -> Linguist -> lupdate.

lupdate reported the results of the search strings to translate.

Runs an external tool «D:\Qt\5.6\mingw49_32\bin\lupdate.exe» D:/AndroidQT/QTProjects/QtLanguage/QtLanguage.pro
Updating 'QtLanguage_ru.ts'...
    Found 4 source text(s) (0 new and 4 already existing)

«D:\Qt\5.6\mingw49_32\bin\lupdate.exe» completed

Next, open the Qt Linguist make translations all rows, marking, which are translated (This is purely a service information for the translator himself)

After you created the translation, save the file and compile the hex file transfer using the utility lrelease. It can be found in Qt Creator in the same place and lupdate, or run out of Qt Linguist: File -> Release.

For use file will need to place it in a directory with the application's executable file.

Dynamic translation of Application

Loading translation app - it's good, but what if you need to change the dynamic translation? Let's look at a simple example where there QComboBox indicating two languages: English and Russian.

Structure of project

  • QtLanguage.pro -project profile;
  • main.cpp - project file with the main function;
  • mainwindow.h - header file of apllication main window;
  • mainwindow.cpp - source file of main window;
  • mainwindow.ui - form of main window.


I prefer to use a graphic designer to create a GUI application, as it accelerates the development, unless you want something complicated in the appearance of the application, so create a window with the following appearance.

In this window, there are:

  • label
  • label_2
  • comboBox

With the transfer of which we will work. Ease of graphic designer is also the fact that it automatically generates retranslateUi () method, which is used to change the translation of all the signatures that are used in the application, although you can own to register manually a similar method, but personally I do not want to waste time on it, which it may very well be created automatically. For example, in this lesson, it looks as follows:

void retranslateUi(QMainWindow *MainWindow)
    MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0));
    label_2->setText(QApplication::translate("MainWindow", "The QTranslator class provides internationalization support for text output.An object of this class contains a set of translations from a source language to a target language. QTranslator provides functions to look up translations in a translation file. Translation files are created using Qt Linguist.", 0));
    label->setText(QApplication::translate("MainWindow", "Select Language", 0));
} // retranslateUi


As mentioned above, indicate the name of the translation file in the project profile.

# Project created by QtCreator 2016-05-22T14:34:42

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = QtLanguage

SOURCES += main.cpp\

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui

TRANSLATIONS = QtLanguage_ru.ts



And here in this file will not change anything.

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
    QApplication a(argc, argv);

    MainWindow w;

    return a.exec();


In the header of the main window of the application must be declared QTranslator object class and override the method changeEvent (QEvent * event) , which will be determined by the application of language change event.


#include <QMainWindow>
#include <QTranslator>
#include <QEvent>

namespace Ui {
class MainWindow;

class MainWindow : public QMainWindow

    explicit MainWindow(QWidget *parent = 0);

    // The method of obtaining the events in the main application window
    // In it will be checked events change transfer applications
    void changeEvent(QEvent * event) override;

    Ui::MainWindow *ui;
    QTranslator qtLanguageTranslator;   // Select the translation in a separate field, otherwise it will not work

#endif // MAINWINDOW_H


The logic of the application is as follows: when you change the item in the combo box will change the translation of the application.

Note. Do not forget to put the translation file with the extension qm next to the application's executable file and collect the required dll , otherwise it not will work.

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>
#include <QTranslator>
#include <QLibraryInfo>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    ui(new Ui::MainWindow)

    // Set two points with the text of the locales in the combo box
    ui->comboBox->addItems(QStringList() << "ru_RU" << "en_US");

    // connect to the signal change of combo box item 
    // to lambda function that will change application translation 
    // where there is an interesting point. 
    // Since QComboBox has an overload signal signatures, 
    // then we need to cast to the desired signal signature. 
    // In this case, we use the name of the item at its change
    connect(ui->comboBox, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentIndexChanged),
            [=](const QString &str){
        qtLanguageTranslator.load("QtLanguage_" + str, ".");   // load translation
        qApp->installTranslator(&qtLanguageTranslator);        // Set the translation in the application

    // Make an initial transfer to the initialization of the application window
    qtLanguageTranslator.load(QString("QtLanguage_") + QString("ru_RU"));

    delete ui;

void MainWindow::changeEvent(QEvent *event)
    // In the case of events changing the application language
    if (event->type() == QEvent::LanguageChange) {
        ui->retranslateUi(this);    // translate the window again


As a result, you will receive an application with support for two languages in its graphical user interface.

Download example of Application with QTranslator

Video lesson

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate

Не работает....

Очень содержательный комментарий. По моему опыту, не работает всегда потому, что кто-то что-то не правильно делает. А в видео показано, что все отлично работает.


А к чему относится такая проблема? Есть QPlainTextEdit. У него есть горячие клавиши. Но они работает только на английском языке : Когда на клавиатуре нажимается ctrl + 'x', горячая клавиша "вырезать" срабатывает. Но при нажатии ctrl + 'ч' не срабатывает. Стоит создать тему на форуме или это что-то само собой разумеющиеся?
Данный код в main.cpp не помог :

    QString translatorFileName = QLatin1String("qt_");
    translatorFileName += QLocale::system().name();
    QTranslator *translator = new QTranslator(&a);
    if (translator->load(translatorFileName, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))

А вы случаем не переводили эти сочетания клавиш там, где они устанавливаются? Если где-то есть этот перевод, то есть там подставлена tr() b trUtf8() функция, то могут быть проблемы, лучше те куски кода не оборачивать в функции перевода и не делать перевода, тем более, что это и не нужно. Скорее всего коды клавиш неправильно определяются.

Скачал пример, увы, не работает. Комбобокс исправно пашет, переключения языков нет.

Ещё подскажите, как без шаманства кастования переключать язык? Например, как это обычно бывает, после перезагрузки приложения.

Странно. Должен был бы работать... проверю на досуге.

Вообще сохраняют инфоромацию о языке в QSettings, который нужно установить. Закрывают приложение и после запуска из QSettings подтягивается инофрмация о локализации приложения, после чего загружается требуемый язык.

Если использовать QComboBox для выбора языка, то с новым синтаксисом сигналов и слотов без каста не получится, но можно использовать шаблонный функционал Qt для упрощения работы с сигналами и слотам. Подробнее в этой статье про QOverload

  • #
  • July 13, 2018, 6:55 a.m.
Хорошая статья. Только один вопрос как это сделать для CMake?

Интересует именно запись в CMakeList

  1. TRANSLATIONS += QtLanguage_ru.ts
Пытался так, но не работает и хотя в документации написано так.


add_custom_target(translations DEPENDS ${TRANSLATION_QM})
Ругается на
пишет - неизвестная команда.

qt5_create_translation понимает, но ничего не происходит.

У меня на руках есть один проект, где какие-то потуги с переводами и подключением этого добра в CMAKE делались.

Но там файл перевода добавляется прямо в ресурсы проекта. То есть бинарных qm файл переводов добавлялся в qrc файл. То есть при компилировании перевод сохранялся как ресурс, а потом уже из ресурсов забирался.

Как понимаю,
qt5_add_translation или qt5_create_translation
Должны ещё создать этот самый бинарный qm файл переводов

Спасибо,  попробую.

Работает так:

find_package (Qt5LinguistTools)
file (GLOB TS_FILES ${SOURCE_DIR}/translations/*.ts)
qt5_add_translation (QM_FILES ${TS_FILES})
add_custom_target (translations ALL DEPENDS ${QM_FILES})


Все работает, кроме одного.
Есть у меня ряд строковых локализуемых констант. Например:

static const QString V01 = "Вариант 01";
static const QString V02 = "Вариант 02";

Потом, они используются в мэпе:

QMap<int, QString> Variants =
    std::pair<int, QString> (1, V01)
  , std::pair<int, QString> (2, V02)

В конце есть функция, возвращающая сроку по коду:

QString variant(const int varCode)
    return Variants.value(varCode);

Как быть в такой ситуации? Константы в tr() не обернешь.

Сделал так:

static const QString V01 = QCoreApplication::tr("Вариант 01");
static const QString V02 = QCoreApplication::tr("Вариант 02");

Лингвист видит эти значения в контексте QCoreApplication,
позволяет их перевести, но доступа к переводу нет,
выводится на русском языке.
Что я делаю не так?

Самая главная проблема в том, что у вас это константные переменные, и инициализируется они один единственный раз при запуске программы.
Поэтому делать динамический перевод в таком случае у вас не получится. Вам нужно иначе подходить к этой проблеме.

Напишите код так.

QString variant(const int varCode)
    switch (varCode)
        case 1: return QCoreApplication::tr("Вариант 01");
        case 2: return QCoreApplication::tr("Вариант 02");
        default: return QString();
  • #
  • Aug. 14, 2019, 12:27 a.m.
  • (edited)

Спасибо большое. Получилось


Only authorized users can post comments.
Please, Log in or Sign up
Looking for a Job?
25,000.00 руб. - 30,000.00 руб.
Разработчик Qt/C++
Barnaul, Altai Krai, Russia

For registered users on the site there is a minimum amount of advertising

Oct. 19, 2019, 1:45 a.m.
Dmitrij Pasynkov

C++ - Test 001. The first program and data types

  • Result:26points,
  • Rating points-10
Oct. 18, 2019, 1:27 p.m.
Artem Sergeevich

C++ - Test 001. The first program and data types

  • Result:13points,
  • Rating points-10
Oct. 18, 2019, 11:05 a.m.
Mihail Bulatov

C++ - Test 001. The first program and data types

  • Result:86points,
  • Rating points6
Last comments
Oct. 17, 2019, 2:17 a.m.
Evgenij Legotskoj

Используем, там где требуется :)
Oct. 17, 2019, 2:15 a.m.
Mikhail Petrov

Совет: подключайте ресурсы динамически. Используйте Resource Compiler: https://doc.qt.io/qt-5/rcc.html
Oct. 16, 2019, 6:45 a.m.
Evgenij Legotskoj

Если это не чистой воды спам, а по делу, то без проблем. Но в таком случае лучше создавайте отдельный вопрос на форуме . При создании вопроса есть поле, в котором можно указать статью…
Oct. 16, 2019, 6:39 a.m.
Kirill Kirilych

А тут можно ссылки на сторонний ресурс показывать? Нашёл на habr похожую статью, только там чуток отличается код и про локальный сервер написано, нужно чтоб кто то понимающий посмотрел и своё …
Now discuss on the forum
Oct. 18, 2019, 1:30 p.m.
Evgenij Legotskoj

Добрый день. У вас там пробелы находятся в тексте, поэтому и не может сконвертировать. фукция map применяет float ко все символам в каждой строке. В том числе и к символам пробела. А пробе…
Oct. 17, 2019, 10:31 a.m.
Ruslan Volshebnik

Я вас понял) Спасибо ещё раз. Вы помогли мне во всём разобраться.
Oct. 17, 2019, 4:13 a.m.

И тебе спасибо за помощь)
Oct. 17, 2019, 2:14 a.m.
Evgenij Legotskoj

Добрый день. Ну да, этот вариант жизнеспособен. Есть только один момент, который вам необходимо понимать в данном случае. И чего в этой статье или нет, или сказано как-то совсем вскользь, …
© EVILEG 2015-2019
Recommend hosting TIMEWEB