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

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 QApplication::tr() function.

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

Linguist tool screen

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 of ui->retranslateUi(this) and updateUI()), but that the calls of the non-visual class occur later the exchange of locale, so the text should be translated correctly.

In the above code, I also came to include the lines marked with comments, but this did not cause the translation to accompany the locale set.

Does anyone have any idea where I might be making a mistake?

Edition:

Qt version is 5.1.0 (32 bit), and I'm 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;

Author: Guilherme Nascimento, 2013-12-11

2 answers

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

To fix or problem definitely , I changed the. pro file to include in the release and debug settings the automated copying of the files to the correct directories:

. . .

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

. . .
 11
Author: Luiz Vieira, 2014-01-14 12:50:21

I use an older version, but as I understand it, the call of TR in your class is wrong.

The documentation says that if your class is not a subclass 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 question is: What do you call it? Below is the example of documentation:

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

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

 4
Author: Marcos Zolnowski, 2014-01-14 12:50:48