Reputation: 330
I am working on a Qt project consisting in a QMainWindow
and multiple Qt and non-Qt classes. Many of them use QStrings with tr()
that are translated with Qt Linguist. The language change (QTranslator
load & install/QTranslator
load & remove) is triggered by QActions in the app's menu.
I have read the official Qt documentation concerning dynamic translation, and it basically suggests 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 the QStrings to translate are many (58 in QMainWindow
alone), and several are filled at runtime as well, through user interaction; e. g. myFunction(a,b)
below is called through a 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")));
}
...
}
So I hardly see how I can include this type of QString
in the changeEvent()
method above. What about the classes outside of MainWindow
, which also have QStrings to translate but are not QWidget
(so no changeEvent
overload possible) ?
I have read that there's another way to use this method, with a UI form:
void MainWindow::changeEvent(QEvent* event)
{
if (event->type() == QEvent::LanguageChange)
{
ui.retranslateUi(this);
}
...
}
But this involves that I am using a UI form in my project, which I am not doing (all widgets are created in code). I tried to export my MainWindow in a UI form, but when I try to include the generated header into the project, I get the following error:
ui_fenetreprincipale.h:32: error: qmainwindowlayout.h: No such file or directory
Thank you by advance for any suggestion to select the best way to translate my application.
Upvotes: 7
Views: 2308
Reputation: 1
I had the same problem, menus not translating, fixed completely by creating and installing the QTranslator...
QScopedPointer<QApplication> app(new QApplication(argc, argv));
QTranslator myappTranslator;
myappTranslator.load(QString("Languages/de"))
app->installTranslator(&myappTranslator);
...before creating and showing the main window...
MainWindow *mainWin;
mainWin = new MainWindow(&splash);
mainWin->show();
Upvotes: 0
Reputation: 739
Organize your code so that all the setting of translatable strings is done in one method in each class.
eg give every class that has translatable strings a setTrs() method that 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")));
}
Then whenever the language for the application changes (eg connect to a menu entry selection, or MainWindow::event() or however the required language can change), you have to manually call the setTrs
method of each of these objects
eg
void MainWindow::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange)
{
setTrs();
objA.setTrs();
objB.setTrs();
}
}
Even more elegant would be to store the objects in a QList and just iterate through it calling the setTrs
method on each element in turn
Upvotes: 3