How to use Qt translations directly with Qapplication::tr()

Asked

Viewed 1,037 times

19

In an application developed in Qt I have a non-visual class (i.e., that is not inherited from a QWidget) but that handles text strings that must be presented to the user. To use the Qt translation engine, I set all strings using the function QApplication::tr().

Strings are correctly displayed in the tool Linguist, in the context of QApplication (as expected - see image below). However, when I see code I change the Locale of the application, only the strings under the context of MainWindow are amended.

Tela da ferramenta Linguist

The code I use to change the language is as follows::

void MainWindow::setLocale(QString sLocale)
{
    QTranslator *pTranslator = m_mpTranslators[sLocale];
    if(pTranslator)
    {
        for(map<QString, QTranslator*>::iterator it = m_mpTranslators.begin(); it != m_mpTranslators.end(); ++it)
        {
            qApp->removeTranslator(it->second);
            QApplication::removeTranslator(it->second); // Essa linha não existia antes!
        }
        qApp->installTranslator(pTranslator);
        QApplication::installTranslator(pTranslator);  // Essa linha também não!

        if(sLocale == "pt_BR")
            m_pLocaleButton->menuAction()->setIcon(QIcon(":/resources/icons/pt_BR"));
        else
            m_pLocaleButton->menuAction()->setIcon(QIcon(":/resources/icons/en_UK"));

        ui->retranslateUi(this);
        updateUI();
    }
}

I think it is important to note that the change of the texts in the graphical interface is immediate (via calls for ui->retranslateUi(this) and updateUI()), but calls from non-visual class occur later the change of the locale, then the text should be translated correctly.

In the code above, I also came to include the lines marked with comments, but this did not make the translation follow the locale defined.

Does anyone have any idea where I might be mistaken?

Editing:

The version of Qt is 5.1.0 (32 bit), and I am running on Windows 7 (64 bit). Translators are created in the class constructor MainWindow, as follows:

// Setup the translation system
QTranslator *pPortuguese = new QTranslator(this);
QString sPortuguese = QCoreApplication::applicationFilePath().replace(".exe", "_pt_BR.qm");
if(pPortuguese->load(sPortuguese))
    m_mpTranslators.insert(map<QString, QTranslator*>::value_type(QString("pt_BR"), pPortuguese));
else
    qWarning() << "Portuguese translation file not found";

QTranslator *pEnglish = new QTranslator(this);
QString sEnglish = QCoreApplication::applicationFilePath().replace(".exe", "_en_UK.qm");
if(pEnglish->load(sEnglish))
    m_mpTranslators.insert(map<QString, QTranslator*>::value_type(QString("en_UK"), pEnglish));
else
    qWarning() << "English translation file not found";

The m_mpTranslators attribute is a simple map that relates the locale string to the translator: std::map<QString, QTranslator*> m_mpTranslators;

  • What version of QT do you use, and where does the Translator? I see mpTranslators, but where and how this variable receives the Translator?

  • Sorry @bigown. I fixed it. :)

  • @Marcoszolnowski, I edited the question to include the information you requested. As I said, the translations work properly for the graphical interface. They do not only work for texts extracted via Qapplication::tr().

  • Downvote for not writing Qt would be worse @bigown :)

2 answers

11


The problem actually stemmed from a flaw (my mistake, Sorry!) in updating the translation files (*.qm) in the build’s target directory. In the file. pro there were no instructions for the automated copy of the translations to the destination directories, and so the tests used an earlier version of the translations (which I had manually copied, probably). This resulted in incorrect text display regardless of the context used.

To solve the problem definitely, i changed the . pro file to include in the release and debug settings the automated copy of the files to the directories correct:

. . .

copyfiles.commands += @echo Copying translation files... &

# Configurações para Windows
win32{

    . . .

    # Troca '/' por '\' nos diretórios de origem e destino
    SOURCE_WIN = $${PWD}
    SOURCE_WIN ~= s,/,\\,g
    TARGET_WIN = $${OUT_PWD}
    TARGET_WIN ~= s,/,\\,g

    debug_and_release {
        CONFIG -= debug_and_release
        CONFIG += debug_and_release
    }

    # Configurações de debug
    CONFIG(debug, debug|release) {
        CONFIG -= debug release
        CONFIG += debug

        . . .

        copyfiles.commands += @call copy $${SOURCE_WIN}\\*.qm $${TARGET_WIN}\\debug\\
    }

    # Configurações de release
    CONFIG(release, debug|release) {
        CONFIG -= debug release
        CONFIG += release

        . . .

        copyfiles.commands += @call copy $${SOURCE_WIN}\\*.qm $${TARGET_WIN}\\release\\
    }

}

# Inclui os comandos de cópia das traduções na execução do QMake
QMAKE_EXTRA_TARGETS += copyfiles
POST_TARGETDEPS += copyfiles

. . .
  • I didn’t expect this, but the only indicator is the file modification date, because you can’t just open the file in the text editor.

  • Please mark the answer to your problem (although you posted it yourself). This will let everyone know that their problem has been solved without having to read the topic.

  • @Renatoutsch: Thanks for the tip. I’ve done as suggested.

4

I use an older version, but from what I understand, the call from TR in your class is wrong.

The documentation says that if your class is not sub-class of QObject, use TR of QCoreApplication:

If the quoted text is not in a Member Function of a Qobject subclass, use either the tr() Function of an appropriate class, or the Qcoreapplication::Translate() Function directly

The point is: in what way you call her? Below is the example of the documentation:

 qApp->translate("LoginWidget", "Password:"),
             logwid);

I find it interesting that this example above should use an instance of QApplication, and he uses translate instead of TR.

  • I just had a test. I was actually quite hopeful because your answer makes a lot of sense. I switched all calls from Qapplication::tr() to qApp->Translate() with a different context (for example: qApp->Translate("Emotiondata", "Aperture of Left Eye"), with the context "Emotiondata"). I retraced some phrases for testing (I even deleted the .qm files and recompile everything), and unfortunately it didn’t work.

  • You can tell by calling qApp->translate("EmotionData", "Aperture of Left Eye") soon after UpdateUI() works? You may have to manually enter the terms, or he wants another context. But knowing if it works right after the call, it helps enough to understand the problem.

  • I ran the test with Qstring s = qApp->Translate("Emotiondata", "Aperture of Left Eye"); qDebug() << "s = " << s; right after the Updateui() call. The result is always in English (which is in the code), regardless of the locale.

  • By the way, what did you mean by "manually enter the terms"? :)

  • Manually would be to manually edit the *.TS files (which I don’t recommend), better use the technique of QT_TR_NOOP(). Yeah, you should have come up with the right text on this test, you ruled all *.qm?

  • Yes, I will. ( I checked the files . ts and even opened the files . qm generated to see if the pt_br content was there (and they are apparently correct. But I don’t really think the problem is in the generation of these files.

  • Is there this context "Emotiondata"? in the *.TS files? Why I decided to do tests of all kinds, with TR, translate, directly into Mainwindow.ui, and running the lupdate all worked.

  • Yes, it does. My process is very standard: after changing the code (adding new strings, for example), I run lupdate. I’ll go over to Qt’s Linguist tool and translate what’s new. Then, I run lrelease to generate the files .qm. Then I go to Qtcreator and recompile everything (to be sure, run qmake again before doing the rebuild).

  • I also did tests using the most diverse forms of translation. The code always compiles well, does not give error of execution, but does not translate! :)

  • Just for the record, the problem was due to a fault of mine in updating the files . qm in the destination directories. I added an answer with what I did to fix it. Please excuse the nonsense. : ) Anyway, +1 for the help! Thank you!

Show 6 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.