Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Translation values returned from C++ models
QtWS25 Last Chance

Translation values returned from C++ models

Scheduled Pinned Locked Moved Solved QML and Qt Quick
7 Posts 4 Posters 88 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    MarNem
    wrote last edited by
    #1

    Hi, I'm facing some problems with translation in a specific case of C++/qml combination. I have a C++ model derived from QAbstractTableModel. The data() function there returns QVariant. In the ui I need to see a translation of returned value. How do I achieve that?
    I followed the steps (described here: https://www.qt.io/blog/qt-quick-multilingual-app-creation), and could translate the application otherwise, it works fine. The problem concerns this specific case when C++ model returns a string from its data() function.
    Here is a snippet:

    import QtQuick
    import QtQuick.VirtualKeyboard
    import QtQuick.Controls
    import tableTest
    
    Window {
        id: window
        width: 250
        height: 250
        visible: true
        title: qsTr("Hello World")
    
        Button {
            width: 70
            height: 40
            anchors.centerIn:parent
            text: qsTr("translate")
            onClicked: {
                Qt.uiLanguage = Qt.uiLanguage === "en" ? "sv" : "en" }
        }
        TableView {
            anchors.fill: parent
            columnSpacing: 1
            rowSpacing: 1
            clip: true
    
            model: MyModel {}
    
            delegate: Rectangle {
                implicitWidth: 100
                implicitHeight: 50
                Text {
                    text: qsTr(display) // not translated
                }
            }
        }
    }
    
    
    
    #include <qqml.h>
    #include <QAbstractTableModel>
    
    class MyModel : public QAbstractTableModel
    {
        Q_OBJECT
        QML_ELEMENT
    
    public:
        int rowCount(const QModelIndex & = QModelIndex()) const override
        {
            return 2;
        }
    
        int columnCount(const QModelIndex & = QModelIndex()) const override
        {
            return 2;
        }
    
        QVariant data(const QModelIndex &index, int role) const override
        {
            switch (role) {
            case Qt::DisplayRole:
                //return QString("%1, %2").arg(index.column()).arg(index.row());
                return m_data[index.row()][index.column()];
            default:
                break;
            }
    
            return QVariant();
        }
    
        QHash<int, QByteArray> roleNames() const override
        {
            return { {Qt::DisplayRole, "display"} };
        }
    private:
        QVector<QVector<QString>> m_data {{tr("One"), tr("Two")}, {tr("Three"), tr("Four")}}; // the ts file has the translation for "One", "Two", "Three" and "Four"
    };
    
    
    1 Reply Last reply
    0
    • M Offline
      M Offline
      MarNem
      wrote last edited by MarNem
      #7

      Seems to work with qsTranslate in qml and QT_TRANSLATE_NOOP in the vector (inspired by http://imaginativethinking.ca/how-the-heck-can-i-use-qstr-with-variables/). Thank you all.

      1 Reply Last reply
      0
      • C Offline
        C Offline
        CassD
        wrote last edited by CassD
        #2

        yes using the tr() function where you define that string is the way to achieve this. The vector declaration is the right place to do this.

        There's no problem in returning a QString in the data function, the string will be implicitly converted to QVariant.
        tr returns a QString, and when you return that string in data, it will be converted to QVariant.

        You can also return QVariant (m_data[index.row()][index.column()]) ; if you estimate that explicitly converting is more understandable or readable to you.

        Edit: ok I didn't see the call to qsTr in your delegate. Remove it. You are trying to retranslate a string that is already translated. Do translate strings when you define them between quotes. Don't translate use tr() or qsTr() on variables.

        1 Reply Last reply
        0
        • GrecKoG Offline
          GrecKoG Offline
          GrecKo
          Qt Champions 2018
          wrote last edited by
          #3

          The vector declaration is not the right place to call tr(). You want to delay that until you display the text in Qt Quick, where it would be reevaluated on language change.

          Use QT_TR_NOOP inside the vector instead of tr and use qsTr like you did in QML.

          More info also here : Use QT_TR_NOOP() for Translatable Data Text Strings

          C 1 Reply Last reply
          1
          • M Offline
            M Offline
            MarNem
            wrote last edited by
            #4

            Thank you for your answers. Unfortunately, even QT_TR_NOOP didn't help.
            Unrelated, but I also forgot "z: -1" for table view.
            Here is the setup that doesn't work either (i.e. "Hello World" and "translate" get translated, but delegates' texts still not...). Basically, none of the combinations of QT_TR_NOOP, tr, qsTr work....

            import QtQuick
            import QtQuick.VirtualKeyboard
            import QtQuick.Controls
            import tableTest
            
            Window {
                id: window
                width: 250
                height: 250
                visible: true
                title: qsTr("Hello World")
            
                Button {
                    width: 70
                    height: 40
                    anchors.centerIn:parent
                    text: qsTr("translate")
                    onClicked: {
                        Qt.uiLanguage = Qt.uiLanguage === "en" ? "sv" : "en";
                    }
                }
                TableView {
                    anchors.fill: parent
                    columnSpacing: 1
                    rowSpacing: 1
                    z: -1
                    clip: true
            
                    model: MyModel {}
            
                    delegate: Rectangle {
                        implicitWidth: 100
                        implicitHeight: 50
                        Text {
                            text: qsTr(display)
                        }
                    }
                }
            }
            
            
            #include <qqml.h>
            #include <QAbstractTableModel>
            
            class MyModel : public QAbstractTableModel
            {
                Q_OBJECT
                QML_ELEMENT
            
            public:
                int rowCount(const QModelIndex & = QModelIndex()) const override
                {
                    return 2;
                }
            
                int columnCount(const QModelIndex & = QModelIndex()) const override
                {
                    return 2;
                }
            
                QVariant data(const QModelIndex &index, int role) const override
                {
                    switch (role) {
                    case Qt::DisplayRole:
                        //return QString("%1, %2").arg(index.column()).arg(index.row());
                        return m_data[index.row()][index.column()];
                    default:
                        break;
                    }
            
                    return QVariant();
                }
            
                QHash<int, QByteArray> roleNames() const override
                {
                    return { {Qt::DisplayRole, "display"} };
                }
            private:
                // NONE of these work in combination with  <qsTr(display)> , <QT_TR_NOOP(display)> or <display> in  the qml file.
                //QVector<QVector<QString>> m_data {{QT_TR_NOOP("One"), QT_TR_NOOP("Two")}, {QT_TR_NOOP("Three"), QT_TR_NOOP("Four")}};
                //QVector<QVector<QString>> m_data {{tr("One"), tr("Two")}, {tr("Three"), tr("Four")}};
                QVector<QVector<QString>> m_data {{"One", "Two"}, {"Three", "Four"}};
            };
            
            1 Reply Last reply
            0
            • GrecKoG GrecKo

              The vector declaration is not the right place to call tr(). You want to delay that until you display the text in Qt Quick, where it would be reevaluated on language change.

              Use QT_TR_NOOP inside the vector instead of tr and use qsTr like you did in QML.

              More info also here : Use QT_TR_NOOP() for Translatable Data Text Strings

              C Offline
              C Offline
              CassD
              wrote last edited by
              #5

              @GrecKo said in Translation values returned from C++ models:

              where it would be reevaluated on language change.

              which is a very frequent occurence yes.

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote last edited by
                #6

                Hi,

                Something just popped to my eye. Usually, custom models use User roles to access their data. See the example here.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  MarNem
                  wrote last edited by MarNem
                  #7

                  Seems to work with qsTranslate in qml and QT_TRANSLATE_NOOP in the vector (inspired by http://imaginativethinking.ca/how-the-heck-can-i-use-qstr-with-variables/). Thank you all.

                  1 Reply Last reply
                  0
                  • M MarNem has marked this topic as solved

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved