How to retranslate an app with stack view?



  • Hey,
    I've been trying to implement a dynamic language change in my app. This is what I did at first:

    //main.cpp
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QApplication app(argc, argv);
    
        qmlRegisterType<CustomClass>("io.qt.CustomClass", 1, 0, "CustomClass");
    
        QTranslator translator;
        translator.load(":/EN.qm");
        app.installTranslator(&translator);
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
        return app.exec();
    }
    
    
    
    //customclass.h
    class CustomClass : public QObject
    {
        Q_OBJECT
    public:
        explicit CustomClass(QObject *parent = nullptr) : QObject(parent) {}
        Q_INVOKABLE void change(){
            QTranslator translator;
            QApplication::removeTranslator(&translator);
            translator.load(":/CZ.qm");
            QApplication::installTranslator(&translator);
            //QQmlApplicationEngine * engine = qobject_cast<QQmlApplicationEngine *>(qmlEngine(this));
            QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
            engine->retranslate();
        }
    };
    
    
    
    //main.qml
    ...
    CustomClass{id:test}
    ...
     ItemDelegate {
                    text: qsTr("Page 1")
                    width: parent.width
                    onClicked: {
                        test.change()
                        drawer.close()
                    }
                }...
    
    
    
    //.pro file
    QT += quick gui core
    ...
    TRANSLATIONS = EN.ts CZ.ts
    ...
    HEADERS += \
        customclass.h
    

    This however only translates only the currently present items on the stack, not the ones pushed after that. I tried to use this workaround restarting the app with new language which kinda works but since QT 5.14 I've encountered a problem that after this reset a keyboard is not appearing when editing text fields. (I have to reset the app manually to have the translated and keyboarded app :D)

    int returnValue = 0;
       do
       {
           QApplication app(argc, argv);
           QTranslator translator;
           translator.load(":/translation/"+langString+".qm"); //langString might be the "CZ" as in the question example
           app.installTranslator(&translator);
    
           QQmlApplicationEngine engine;
           engine.load(QUrl(QStringLiteral("qrc:/src/qml/main.qml")));
           if (engine.rootObjects().isEmpty())
               return -1;
    
           returnValue = app.exec();
    
           langString = settings.value("language").toString();
       }
       while(returnValue == TRANSLATION_RESTART);
    
    
       return returnValue;
    
    
    
    //I can then call somewhere
     qApp->exit(TRANSLATION_RESTART);
    //when I need the retranslation
    

    Is there any recommended approach or working solution to change the language when using Stackview on Android? I wonder what's wrong with this second method. Did I miss something when resetting the app?
    Thanks and have a nice day!


  • Lifetime Qt Champion

    Hi,

    One thing I can see is that your translator will be destroyed at the end of the function which isn't what you want.

    Restarting the application should not be needed.



  • @SGaist said in How to retranslate an app with stack view?:

    Hi,

    One thing I can see is that your translator will be destroyed at the end of the function which isn't what you want.

    Restarting the application should not be needed.

    You were right! Such a stupid mistake, thanks! For the rest I used the approach about translator singleton class with a wrapper registered type for communication mentioned here.


  • Lifetime Qt Champion

    Great ! Thanks for sharing !

    Since you have it working now, please mark the thread as solved using the "Topic Tools" button so that other forum users may know a solution has been found :-)


Log in to reply