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)

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

  • #
  • Nov. 19, 2019, 1:10 p.m.

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


Все переводится кроме тултипов.
Не подскажете куда копать?

Добрый день.

Вы используете QGraphicsItem? вообще побольшу бы кусок кода, чтобы иметь большее представление. Мысли есть, но не уверен

  • Pan
  • #
  • Nov. 20, 2019, 2:10 a.m.
  • (edited)

да, есть классы наследуемые от QGraphicsItem.
в программе при нажатии определенных кнопок(слева на картинке), на сцене появляются Item-ы
с разными настройками. в конструкторе ни чего особого нет,только координаты,название,тултип.

перевод загружается так

int main(int argc, char *argv[])
    QApplication a(argc, argv);
    QTranslator translator;
    MainWindow w;

    return a.exec();

Вообще, метод tr является частью класса QObject, если он у вас используется в конструкторе, то вы должны были использовать множественное наследование для вашей кастомной кнопки. Поскольку графические объекты одни из немногих классов, которые не наследуются от QObject, кроме QGraphicsObject, но там также множественное наследование используется.

То есть заголовочный код вашей кнопки должен выглядеть так

class Button : public QObject, public QGraphicsItem
    /* и так далее */

Убедитесь, что у вас присутсвует макрос Q_OBJECT, он отвечает за мета информацию и включение возможности перевода.

Если же вы не наследовались от QObject, то перевод можно также включить с помощью другого макроса

class Button : public QGraphicsItem
    /* и так далее */

И в качестве дополнения из личного опыта. Пишите лучше все тексты на английском языке в функциях tr )))


у меня множественное наследование.
сначала основной класс myitem

class myItem : public QObject, public QGraphicsItem
    myItem(int x, int y, int w, int h);

со всякими переменными.

а потом от него все остальные , которые появляются на сцене.

"Пишите лучше все тексты на английском языке в функциях tr"
понимаю, просто программа очень спецефическая(это конфигуратор для устройства на микроконтроллере)
и не планировалась для других языков. но потом подтянулись иностранные граждане и попросили перевести..

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

myButton::myButton(int x, int y, int w, int h) : myItem (x, y, w, h)
  static int i = 1;
  myVar.text = "Btn" + QString::number(i++);
  myVar.myType = typeSimpleButton;
  myVar.func_read = 1;
  configVisibleWidgets |= 1<<visibleSettings::Hsize | 1<<visibleSettings::Wsize
      | 1<<visibleSettings::Color1 | 1<<visibleSettings::ColorText | 1<<visibleSettings::Color2
      | 1<<visibleSettings::TextEdit | 1<<visibleSettings::ModbusWrite
      | 1<<visibleSettings::Toggle | 1<<fontSizeSelect | 1<<itSlave;
myItem::myItem(int x, int y, int w, int h)
  myVar.rect.x =x;
  setFlags(QGraphicsItem::ItemIsMovable |
           QGraphicsItem::ItemIsSelectable |

при этом тултипы заданные в редакторе форм переводятся...

проблема в конструкторе, напишите так

myItem::myItem(int x, int y, int w, int h) : QObject()
  myVar.rect.x =x;
  setFlags(QGraphicsItem::ItemIsMovable |
           QGraphicsItem::ItemIsSelectable |

добавил : QObject()
ни чего не изменилось.

ладно. что-нибудь придумаю

Тогда хоть убейте, не знаю. Где-то не хватает или макроса или корректной реализации конструктора.


Only authorized users can post comments.
Please, Log in or Sign up
How to become an author?

Contribute to the evolution of the EVILEG community.

Learn how to become a site author.

Learn it

Good day, Dear Users!!!

I am Evgenii Legotckoi, developer of EVILEG. And it is my hobby project, which helps to learn programming another programmers and developers

If the site helped you, and you want also support the development of the site, than you can donate by following ways


Let me recommend you the excellent hosting on which EVILEG is located.

For many years, Timeweb has been proving his stability.

For projects on Django I recommend VDS hosting

View Hosting Timeweb
May 26, 2020, 11:29 a.m.
Artem Sun-Dun-Chan

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
May 25, 2020, 11:33 a.m.
Mitja Nagibin

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
May 25, 2020, 5:05 a.m.

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

  • Result:66points,
  • Rating points-1
Last comments
May 28, 2020, 3:14 p.m.
Evgenij Legotskoj

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Ну в моём примере, который в статье сработало так model->setData(model->index(1, 1), 7); Поскольку model->index(1, 0) - это индекс колонки id, которая скрыта, поэтому…
May 28, 2020, 3:08 p.m.
Mihail A

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Спасибо, завтра првоерю. А model->setData(model->index(1, 0), 7); Тоже заработало?
May 28, 2020, 3:06 p.m.
Evgenij Legotskoj

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Да, метод data всё-таки влиял, я переписал его так и заработало удаление QVariant TableModel::data(const QModelIndex &idx, int role) const{ if (role == Qt::BackgroundColorRole) {…
May 28, 2020, 2:49 p.m.
Evgenij Legotskoj

Django - Tutorial 011. Adding comments to the site based on Django

Он более функциональный и его функционал объективно лучше поддерживается Django. Из первого, что приходит на ум: Это наличие полей типа Array Поддержка полей для JSON …
May 28, 2020, 2:42 p.m.

Django - Tutorial 011. Adding comments to the site based on Django

а в чем явное преимущество postgresql над mysql?)
Now discuss on the forum
May 29, 2020, 1:55 a.m.
Igor' Poroshin

QTablwView + QSqlQueryModel скрыть пустой столбец

Да, понятно. В данном случае лучше использовать серверную процедуру (если такие поддерживаются), в которой будет проверяться наличие всех пустых строк у нужного столбца и вызываться соответ…
May 28, 2020, 6:21 p.m.
Rovshan Gurbanov

Сборка под старые версии Android

У меня SDK почти все версии есть, NDK есть версии 10, 17, 21. Но собирается приложение только с NDK v21 под Android версии 7.0 и выше Версия Qt у меня 5.14.2
May 28, 2020, 7:58 a.m.
Evgenij Legotskoj

Освобождение памяти QMainWindow::setCentralWidget

Да, соглашусь. Просто удаление происходит позже, а не сразу.
May 28, 2020, 5:43 a.m.

При подключении к git как указать пароль?

Нужно сделать ssh-keygen и потом полученый из файла код скопировать в ssh ключ в бикбакете
May 28, 2020, 1:42 a.m.


Да, проблема ушла, спасибо.
© EVILEG 2015-2020
Recommend hosting TIMEWEB