Search code examples
c++qtqtranslator

Why language packs have to be loaded before main window is created in Qt?


I just learned how to set a language pack for my app in Qt, and I am currently have two questions. I wrote a minimal app to show where confused me.
I created a main window, which only contains a QLabel to show text and a QPushButton to change label text from Chinese to English.
And here is my code:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    chineseTr = new QTranslator;
    chineseTr->load("../untitled/Language-Pack_zh-CN.qm");
    englishTr = new QTranslator;
    englishTr->load("../untitled/Language-Pack_en-US.qm");
    QCoreApplication::installTranslator(chineseTr);

    mWidget = new QWidget;
    setCentralWidget(mWidget);
    hLayout = new QHBoxLayout;
    mWidget->setLayout(hLayout);
    mLbl = new QLabel;
    mLbl->setText(tr("Text"));
    translateBtn = new QPushButton;
    connect(translateBtn, &QPushButton::clicked, this, &MainWindow::translateText);
    hLayout->addWidget(mLbl);
    hLayout->addWidget(translateBtn);
}

void MainWindow::translateText()
{
    QCoreApplication::removeTranslator(chineseTr);
    QCoreApplication::installTranslator(englishTr);
}

Question One:
As you can see in the constructor, I loaded the language pack first, or the QLabel will just not show Chinese text. I can either load the Chinese language pack before creating everything else in the constructor, or load in main.cpp before creating MainWindow object. Am I getting this wrong or those language packs just have to be loaded before creating class objects?

Question Two:
As you can see in the code, I clicked the button and to remove the Chinese language pack and install the new translator to load the English language pack. But nothing works. So how can I change language dynamically in the app? I know this question may be simple, but I do not find any useful example online to show me how to do this? So can someone show me a way to do this or give me a hint?

Hope I explain myself clearly, and thanks in advance.


Solution

  • It's important to understand where translation happens: inside tr(...) call. tr(...) returns the translated text. Which means, that replacing translator will influence subsequent calls to tr(...), but have no chance to change texts already displayed in widgets.

    Easiest way to do "switch language on the fly" is to introduce method containing all tr(...) calls and call it after replacing translator and in constructor. I believe that code generated from .ui (the ones created by QtDesigner) files already has such method.

    void MainWindow::translate()
    {
         mLbl->setText(tr("Text"));
    }
    
    void MainWindow::translateText()
    {
        QCoreApplication::removeTranslator(chineseTr);
        QCoreApplication::installTranslator(englishTr);
        translate();
    }