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")); qApp->installTranslator(&qtLanguageTranslator); MainWindow w; w.show(); 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_2->setText(tr("Hello")); 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:
- 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.
- lrelease - program for the compile of the final translation file to be used in the application.
- 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 CODECFORSRC = UTF-8
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.
mainwindow.ui
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
QtLanguage.pro
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 TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp HEADERS += mainwindow.h FORMS += mainwindow.ui TRANSLATIONS = QtLanguage_ru.ts CODECFORSRC = UTF-8
main.cpp
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; w.show(); return a.exec(); }
mainwindow.h
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.
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTranslator> #include <QEvent> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); protected: // 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; private: Ui::MainWindow *ui; QTranslator qtLanguageTranslator; // Select the translation in a separate field, otherwise it will not work }; #endif // MAINWINDOW_H
mainwindow.cpp
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) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // 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")); qApp->installTranslator(&qtLanguageTranslator); } MainWindow::~MainWindow() { 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 } }
Result
As a result, you will receive an application with support for two languages in its graphical user interface.
Download example of Application with QTranslator
Не работает....
Очень содержательный комментарий. По моему опыту, не работает всегда потому, что кто-то что-то не правильно делает. А в видео показано, что все отлично работает.
А к чему относится такая проблема? Есть QPlainTextEdit. У него есть горячие клавиши. Но они работает только на английском языке : Когда на клавиатуре нажимается ctrl + 'x', горячая клавиша "вырезать" срабатывает. Но при нажатии ctrl + 'ч' не срабатывает. Стоит создать тему на форуме или это что-то само собой разумеющиеся?
Данный код в main.cpp не помог :
А вы случаем не переводили эти сочетания клавиш там, где они устанавливаются? Если где-то есть этот перевод, то есть там подставлена tr() b trUtf8() функция, то могут быть проблемы, лучше те куски кода не оборачивать в функции перевода и не делать перевода, тем более, что это и не нужно. Скорее всего коды клавиш неправильно определяются.
Странно. Должен был бы работать... проверю на досуге.
Если использовать QComboBox для выбора языка, то с новым синтаксисом сигналов и слотов без каста не получится, но можно использовать шаблонный функционал Qt для упрощения работы с сигналами и слотам. Подробнее в этой статье про QOverload
У меня на руках есть один проект, где какие-то потуги с переводами и подключением этого добра в CMAKE делались.
Спасибо, попробую.
Здравствуйте!
Все работает, кроме одного.
Есть у меня ряд строковых локализуемых констант. Например:
Потом, они используются в мэпе:
В конце есть функция, возвращающая сроку по коду:
Как быть в такой ситуации? Константы в tr() не обернешь.
Сделал так:
Лингвист видит эти значения в контексте QCoreApplication,
позволяет их перевести, но доступа к переводу нет,
выводится на русском языке.
Что я делаю не так?
Самая главная проблема в том, что у вас это константные переменные, и инициализируется они один единственный раз при запуске программы.
Поэтому делать динамический перевод в таком случае у вас не получится. Вам нужно иначе подходить к этой проблеме.
Напишите код так.
Спасибо большое. Получилось
Здравствуйте.
Спасибо за статью. Сделал перевод программы. Все работает.
Только я делал не динамический, но это пока и не надо.
Но с одной проблемой все же столкнулся.
В программе есть сцена. На ней создаются некие графические элементы.
в конструкторе элементов устанавливаю всплывающую подсказку,
например такую
Все переводится кроме тултипов.
Не подскажете куда копать?
Добрый день.
Вы используете QGraphicsItem? вообще побольшу бы кусок кода, чтобы иметь большее представление. Мысли есть, но не уверен
да, есть классы наследуемые от QGraphicsItem.
в программе при нажатии определенных кнопок(слева на картинке), на сцене появляются Item-ы
с разными настройками. в конструкторе ни чего особого нет,только координаты,название,тултип.
перевод загружается так
Вообще, метод tr является частью класса QObject, если он у вас используется в конструкторе, то вы должны были использовать множественное наследование для вашей кастомной кнопки. Поскольку графические объекты одни из немногих классов, которые не наследуются от QObject, кроме QGraphicsObject, но там также множественное наследование используется.
То есть заголовочный код вашей кнопки должен выглядеть так
Убедитесь, что у вас присутсвует макрос Q_OBJECT, он отвечает за мета информацию и включение возможности перевода.
Если же вы не наследовались от QObject, то перевод можно также включить с помощью другого макроса
И в качестве дополнения из личного опыта. Пишите лучше все тексты на английском языке в функциях tr )))
у меня множественное наследование.
сначала основной класс myitem
со всякими переменными.
а потом от него все остальные , которые появляются на сцене.
"Пишите лучше все тексты на английском языке в функциях tr"
понимаю, просто программа очень спецефическая(это конфигуратор для устройства на микроконтроллере)
и не планировалась для других языков. но потом подтянулись иностранные граждане и попросили перевести..
Покажите, как выглядит реализация конструктора. Поскольку на данный момент я не вижу причин, чтобы переводы не работали.
при этом тултипы заданные в редакторе форм переводятся...
проблема в конструкторе, напишите так
добавил : QObject()
ни чего не изменилось.
ладно. что-нибудь придумаю
Тогда хоть убейте, не знаю. Где-то не хватает или макроса или корректной реализации конструктора.