How to dynamically relay all widgets in an application through a menu?

I am working on a Qt project consisting of QMainWindow and several Qt and non-Qt classes. Many of them use QStrings with tr() , which are translated using Qt Linguist. Changing the language ( QTranslator download and install / QTranslator download and uninstall) is started by QActions in the application menu.

I read the official Qt documentation regarding dynamic translation and basically offers the following overload:

 void MainWindow::changeEvent(QEvent *event) { if (event->type() == QEvent::LanguageChange) { titleLabel->setText(tr("Document Title")); ... // all my tr() QStrings here okPushButton->setText(tr("&OK")); } else QWidget::changeEvent(event); } 

The problem I am facing is that QStrings for translation are many (only 58 in QMainWindow ), and some are populated at runtime, as well as through user interaction; QPushButton . myFunction(a,b) below is called via QPushButton :

 void MainWindow::myFunction(MyClassA a, MyClassB b) { ... if(b.myCondition() == 0) { ... // below is the problem myLabel->setText(myLabel->text() + QString("\n" + a->getName() + tr(" gagne ") + exp + tr(" points d'expérience"))); } else { myLabel->setText(QString(tr("something else"))); } ... } 

Therefore, I hardly see how to include this type of QString in the changeEvent() method described above. What about classes outside MainWindow that also have QStrings for translation but are not QWidget (so no changeEvent overload is possible)?

I read that there is another way to use this method with a user interface form:

 void MainWindow::changeEvent(QEvent* event) { if (event->type() == QEvent::LanguageChange) { ui.retranslateUi(this); } ... } 

But this is due to the fact that I use the UI form in my project, which I do not do (all widgets are created in the code). I tried to export my MainWindow in the form of a user interface, but when I try to include the generated header in the project, I get the following error:

 ui_fenetreprincipale.h:32: error: qmainwindowlayout.h: No such file or directory 

Thank you for your preliminary offer to choose the best way to translate my application.

+5
source share
1 answer

Organize your code so that all translatable string settings are done in a single method in each class.

for example, give each class that has translatable strings the setTrs () method, which actually sets the strings.

 class A { void setTrs() { okPushButton->setText(tr("&OK")); } } //-------------- class B { int _trCond; void myFunction(MyClassA a, MyClassB b) { _trCond = b.myCondition(); setTrs(); } void setTrs() { if(_trCond == 0) myLabel->setText(myLabel->text() + QString("\n" + a->getName() + tr(" gagne ") + exp + tr(" points d'expérience"))); else myLabel->setText(QString(tr("something else"))); } 

Each time you change the application language (for example, connecting to the selection of a menu item or MainWindow :: event (), but perhaps the required language may change), you must manually call the setTrs method for each of these objects

eg,

 void MainWindow::changeEvent(QEvent *event) { if (event->type() == QEvent::LanguageChange) { setTrs(); objA.setTrs(); objB.setTrs(); } } 

It would be even more elegant to store objects in a QList and simply setTrs through it the setTrs method for each element in turn

+2
source

All Articles