Cannot Translate QT Quick Properties Dynamically



  • Hello guys, it is me again :(
    I have my application translated very well. Every part of it is translating dynamically by an empty string as shown,

    caption: qsTr("Hello") + mytrans.emptyString
    

    "mytrans" is my translator as you can guess.
    Only properties of a menu which are on SGlobal.qml is not translating dynamically. I should restart application to make menu labels translated. Code examples I am talking about,

    mediaModel.append(
                       {
                            name: qsTr("Screen Divider"),
                            st: "ScreenDivider",
                            bg: "qrc:/design/media/leftmenu/screendivider.png"
                        }
                        );
    mediaModel.append(
                       {
                        name: qsTr("Television"),
                        st: "Television",
                        bg: "qrc:/design/media/leftmenu/tv.png"
                        }
                        );
    

    How do I make them translate dynamically? Thanks!



  • @closx you have the solution under your eyes... simply add + mytrans.emptyString:

    mediaModel.append(
                       {
                            name: qsTr("Screen Divider")+ mytrans.emptyString
                            st: "ScreenDivider"
                            bg: "qrc:/design/media/leftmenu/screendivider.png"
                        }
                        );
    mediaModel.append(
                       {
                        name: qsTr("Television")+ mytrans.emptyString
                        st: "Television"
                        bg: "qrc:/design/media/leftmenu/tv.png"
                        }
                        );
    


  • Well, thanks for answer. Of course I have tried that hahahaha!
    Look, there are commas. In original, it is something like,

    mediaModel.append({name:qsTr("Screen Divider"),st: "ScreenDivider",bg: "qrc:/design/media/leftmenu/screendivider.png"});
    

    also tried,

    mediaModel.append(
                       {
                        name: qsTr("Television") + mytrans.emptyString,
                        st: "Television",
                        bg: "qrc:/design/media/leftmenu/tv.png"
                        }
                        );
    
    mediaModel.append(
                       {
                        name: (qsTr("Television") + mytrans.emptyString),
                        st: "Television",
                        bg: "qrc:/design/media/leftmenu/tv.png"
                        }
                        );
    
    mediaModel.append(
                       {
                        name: qsTr("Television"),
                        st: "Television",
                        bg: "qrc:/design/media/leftmenu/tv.png"
                        }
                        ) + mytrans.emptyString;
    
    

    any of em wont change anything :(


  • Moderators

    @closx
    you could also delete mediaModel and recreate it.



  • @closx According to you r previous question about translation, this must work:

    ListModel{
        id: tmodel
        ListElement {
            name: qsTr("Left Window") + mytrans.emptyString
            st:"LeftWindow"
    
        }
        ListElement {
            name: qsTr("Right Window") + mytrans.emptyString
            st:"RightWindow"
        }
    }
    
    Repeater {
        model:tmodel
        Text {
            text: name
        }    
    }
    

    I do something similar in my application and it works very well.



  • @KroMignon Allright, your solution have worked for my last problem, but not for my current situation. sorry for being noobish, I have tried to change my code as you wrote. But after long tries, your solution worked for my last problem. But it is not working in current situation. My edited code is,

    ListModel {
        id: controlsModel
        ListElement {
           name: qsTr("Tables") + mytrans.emptyString
           st: "Tables"
           bg: "qrc:/design/controls/leftmenu/tables.png"
        }
        ListElement {
            name: qsTr("Curtains") + mytrans.emptyString
            st: "Curtains"
            bg: "qrc:/design/controls/leftmenu/curtains.png"
        }
        ListElement {
            name: qsTr("Refrigerator") + mytrans.emptyString
            st: "Refrigerator"
            bg: "qrc:/design/controls/leftmenu/refrigerator.png"
        }
        ListElement {
            name: qsTr("Safe Box") + mytrans.emptyString
            st: "SafeBox"
            bg: "qrc:/design/controls/leftmenu/safebox.png"
        }
        ListElement {
            name: qsTr("Air Condition") + mytrans.emptyString
            st: "AirConditioner"
            bg: "qrc:/design/controls/leftmenu/airconditioner.png"
        }
        ListElement {
            name: qsTr("Smoke Fan") + mytrans.emptyString
            st: "SmokeFan"
            bg: "qrc:/design/controls/leftmenu/smokefan.png"
        }
        ListElement {
            name: qsTr("Windows") + mytrans.emptyString
            st: "Windows"
            bg: "qrc:/design/controls/leftmenu/windows.png"
        }
        ListElement {
            name: qsTr("Bar") + mytrans.emptyString
            st: "Bar"
            bg: "qrc:/design/controls/leftmenu/bar.png"
        }
        ListElement {
            name: qsTr("Espresso") + mytrans.emptyString
            st: "Espresso"
            bg: "qrc:/design/controls/leftmenu/espresso.png"
        }
        ListElement {
            name: qsTr("Roof") + mytrans.emptyString
            st: "Roof"
            bg: "qrc:/design/controls/leftmenu/roof.png"
        }
    }
    
        Repeater {
            model:controlsModel
            Text {
                text: name
            }
    }
    

    And the error output is,

    qrc:/SGlobal.qml:691 ListElement: cannot use script for property value
    15:31:38: /home/closx/build-ProAutoVip-Desktop_Qt_5_12_3_GCC_64bit-Debug/autovip_ls/autovip_ls exited with code 255
    

    @J-Hilk What you mean by deleting and recreating it? I would write the same codes even if I would delete :D Again, sorry for being noobish!



  • @closx no problem, I also had to learn many things to be able to work with Qt/QML!

    Just question about mytrans, I think it is an instance of something like this:

    class TranslationHelper : public QObject
    {
        // Q_OBJECT is important to have signal/slot working
        Q_OBJECT
    
        Q_PROPERTY(QString emptyString     READ emptyString     NOTIFY languageChanged)
    
    public:
        explicit TranslationHelper(QObject *parent = nullptr);
    
        QString emptyString() const
        {
            return QString();
        }
    
    signals:
        void languageChanged();
    };
    

    Can you confirm or show your differences?



  • @KroMignon Yep, true. Full code,

    class Translator : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString emptyString READ getEmptyString NOTIFY languageChanged)
    
    public:
        Translator(QGuiApplication* app) { mApp = app; }
    
        QString getEmptyString() { return ""; }
    
    signals:
        void languageChanged();
    
    public slots:
        void updateLanguage(int lang){
            switch(lang){
            case Langs::AR:
                mTranslator.load("general_AR", ":/translator");
                mApp->installTranslator(&mTranslator);
                break;
            case Langs::JAP:
                mTranslator.load("general_JA", ":/translator");
                mApp->installTranslator(&mTranslator);
                break;
            case Langs::TR:
                mTranslator.load("general_TR", ":/translator");
                mApp->installTranslator(&mTranslator);
                break;
            default:
                mApp->removeTranslator(&mTranslator);
                break;
            }
            emit languageChanged();
        }
    
    private:
        QGuiApplication* mApp;
        QTranslator mTranslator;
    };
    


  • @closx said in Cannot Translate QT Quick Properties Dynamically:

    qrc:/SGlobal.qml:691 ListElement: cannot use script for property value

    ah, I am stupid! Sorry, I was wrong. This a known Qt/QML bug ==> QTBUG-16289
    In my application, I don't use ListModel/ListElement, I use an array of QtObject.
    I do something similar to this
    a. define a base type => MyElement.qml

    import QtQuick 2.0
    
    QtObject {
        property string name: ""
        property string st: ""
        property string bg: ""
    }
    

    b. then use it:

    property list<MyElement> myModel: [
        MyElement{
            name: qsTr("Left Window") + mytrans.emptyString
            st:"LeftWindow"
        },
        MyElement{
            name: qsTr("Right Window") + mytrans.emptyString
            st:"RightWindow"
        }
    ]
    
    //Repeater {
    //   model: myModel.length
    //    Text {
    //        text: myModel[index].name
    //    }    
    //}
    Repeater {
        model: myModel
        Text {
            text: model.name
        }    
    }
    
    


  • @KroMignon said in Cannot Translate QT Quick Properties Dynamically:

    mytrans.emptyString

    I just finished translating an application with more than 3000 entries. qsTr worked fine for everything I needed to translate on the QML side.

    What is this "mytrans.emptyString" construct and what does it do?



  • @fcarney mytrans.emptyString is only a fake, it always returns an empty string.
    It is used to force re-calling qrTr() to get new string for current language.
    After changing language / TS file, the corresponding signal is triggered, so translation string are updated without having to restart application.

    Take a look at https://wiki.qt.io/How_to_do_dynamic_translation_in_QML for more details.



  • @KroMignon said in Cannot Translate QT Quick Properties Dynamically:

    without having to restart application

    Interesting. For now we restart the app. I didn't realize QML would not update if you tried to do it dynamically. Thanks!



  • @KroMignon Hey! I forgot to answer to you! Did not meant to be rude and sorry for that :(
    Conclusion: I gave some tries with your suggest and lots of other stuff on internet, but failed :D
    So I have created a "Restart the system to apply all the language changes" screen and a "restart/cancel" choice on a language change state. I guess it will be okay even if it wont be "real-time" :P
    Good Work!