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. How can I get the application QmlEngine ?
QtWS25 Last Chance

How can I get the application QmlEngine ?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
38 Posts 4 Posters 8.4k 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.
  • K Offline
    K Offline
    kmarconi
    wrote on 30 Nov 2020, 12:53 last edited by
    #1

    Hi everyone,

    I'm posting here because I'm stuck on a problem of getting the engine of the main application in other classes. For the moment, I've tried several method like :

    QQmlApplicationEngine* engine = qobject_cast<QQmlApplicationEngine*>(qmlEngine(this));
    QQmlEngine * engine = qmlEngine(this);
    QQmlEngine* engine = QQmlEngine::contextForObject(this)->engine();

    Why I want this engine is because I need a class to restranslate my app when I want it. For the moment, none of these ideas worked and either they are making the app unable to start nor the app is crashing when calling the function to retranslate (engine->retranslate())

    If you have any idea on how could I successfully use the main engine of my app in other classes, I would be glad to hear it.

    Thanks !

    J 1 Reply Last reply 30 Nov 2020, 13:00
    1
    • K kmarconi
      30 Nov 2020, 12:53

      Hi everyone,

      I'm posting here because I'm stuck on a problem of getting the engine of the main application in other classes. For the moment, I've tried several method like :

      QQmlApplicationEngine* engine = qobject_cast<QQmlApplicationEngine*>(qmlEngine(this));
      QQmlEngine * engine = qmlEngine(this);
      QQmlEngine* engine = QQmlEngine::contextForObject(this)->engine();

      Why I want this engine is because I need a class to restranslate my app when I want it. For the moment, none of these ideas worked and either they are making the app unable to start nor the app is crashing when calling the function to retranslate (engine->retranslate())

      If you have any idea on how could I successfully use the main engine of my app in other classes, I would be glad to hear it.

      Thanks !

      J Offline
      J Offline
      J.Hilk
      Moderators
      wrote on 30 Nov 2020, 13:00 last edited by
      #2

      @kmarconi said in How can I get the application QmlEngine ?:

      QQmlApplicationEngine

      As of right now, I do not know of an easy way to get the engine without passing it on via reference or pointer.

      what's this supposed to be actually ?

      qobject_cast<QQmlApplicationEngine*>(qmlEngine(this));
      

      qmlEngine(this);

      Why don't you forward a signal to your main.cpp and simply connect there to retranslate?


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      0
      • K Offline
        K Offline
        kmarconi
        wrote on 30 Nov 2020, 13:11 last edited by kmarconi
        #3

        What I do actually is passing a reference of the engine into my class of translation. But since I never create an engine, could it be the reason why it is not working ?

        what's this supposed to be actually ?

        qobject_cast<QQmlApplicationEngine*>(qmlEngine(this));
        

        This is one of the way I found to get the engine.
        The problem here I think is that in each example I see which are restranlating their apps, they are using only one cpp file and one qml file so they just simply create an engine in the main and load the qml in it. But for me, it's not possible because I have a lot of classes and since one of them is already using my "main.qml" file (its a class heriting from QQuickView which use the qml file with the function "SetSource"), I canno't create another engine to load the qml file because it is making my app crash. I'm pretty sure that what I just wrote is not clear so don't hesitate don't ask me whatever you want.

        EDIT: If I try to qDebug my engine, I see : QObject(0x0) which means that my problem is with my way to get the engine.

        Thanks for your quick answer !

        J 1 Reply Last reply 30 Nov 2020, 13:43
        0
        • K kmarconi
          30 Nov 2020, 13:11

          What I do actually is passing a reference of the engine into my class of translation. But since I never create an engine, could it be the reason why it is not working ?

          what's this supposed to be actually ?

          qobject_cast<QQmlApplicationEngine*>(qmlEngine(this));
          

          This is one of the way I found to get the engine.
          The problem here I think is that in each example I see which are restranlating their apps, they are using only one cpp file and one qml file so they just simply create an engine in the main and load the qml in it. But for me, it's not possible because I have a lot of classes and since one of them is already using my "main.qml" file (its a class heriting from QQuickView which use the qml file with the function "SetSource"), I canno't create another engine to load the qml file because it is making my app crash. I'm pretty sure that what I just wrote is not clear so don't hesitate don't ask me whatever you want.

          EDIT: If I try to qDebug my engine, I see : QObject(0x0) which means that my problem is with my way to get the engine.

          Thanks for your quick answer !

          J Offline
          J Offline
          J.Hilk
          Moderators
          wrote on 30 Nov 2020, 13:43 last edited by
          #4

          @kmarconi
          true, I don't quite get it, do you have multiple QQmlEngines inside your Project ?


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          K 1 Reply Last reply 30 Nov 2020, 13:52
          0
          • J J.Hilk
            30 Nov 2020, 13:43

            @kmarconi
            true, I don't quite get it, do you have multiple QQmlEngines inside your Project ?

            K Offline
            K Offline
            kmarconi
            wrote on 30 Nov 2020, 13:52 last edited by
            #5

            @J-Hilk Nop, sorry. I have for the moment none QQmlEngines inside my project. To display my app, I have a class heriting from QQuickView which is using OpenGL to display my app via the function myView.SetSources("qrc:/main.qml"). After some googling, every example I found for dynamic translation are done in three steps : remove the actual QTranslator, install the new one and then retranslate the app. But in each of these examples, they are doing this line : engine->load(QUrl("qrc:/main.qml")) at first. If i do this line, my app is immediatly crashing because the qml file is already in use in the class which display the app. Let's say this class's name is "myView", I also tried to get the engine by doing : QQmlEngine* engine = QQmlEngine::contextForObject(&myView)->engine(); but my app is directly crashing.

            J 1 Reply Last reply 30 Nov 2020, 13:56
            0
            • K kmarconi
              30 Nov 2020, 13:52

              @J-Hilk Nop, sorry. I have for the moment none QQmlEngines inside my project. To display my app, I have a class heriting from QQuickView which is using OpenGL to display my app via the function myView.SetSources("qrc:/main.qml"). After some googling, every example I found for dynamic translation are done in three steps : remove the actual QTranslator, install the new one and then retranslate the app. But in each of these examples, they are doing this line : engine->load(QUrl("qrc:/main.qml")) at first. If i do this line, my app is immediatly crashing because the qml file is already in use in the class which display the app. Let's say this class's name is "myView", I also tried to get the engine by doing : QQmlEngine* engine = QQmlEngine::contextForObject(&myView)->engine(); but my app is directly crashing.

              J Offline
              J Offline
              J.Hilk
              Moderators
              wrote on 30 Nov 2020, 13:56 last edited by
              #6

              @kmarconi ok I get it,

              QQuickView has a getter for the internal QQmlEngine
              https://doc.qt.io/qt-5/qquickview.html#engine

              call that and simply call retranslate on that returned object, and you should be fine


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              K 1 Reply Last reply 30 Nov 2020, 13:59
              1
              • J J.Hilk
                30 Nov 2020, 13:56

                @kmarconi ok I get it,

                QQuickView has a getter for the internal QQmlEngine
                https://doc.qt.io/qt-5/qquickview.html#engine

                call that and simply call retranslate on that returned object, and you should be fine

                K Offline
                K Offline
                kmarconi
                wrote on 30 Nov 2020, 13:59 last edited by
                #7

                @J-Hilk Wow I think you saved my life here, thanks ^^ My app is finally not crashing anymore but I have now an error from my main.qml file : QML StackView: Binding loop detected for property "button". Any idea on why this could happen ?

                Big thanks.

                J 1 Reply Last reply 30 Nov 2020, 14:03
                0
                • K kmarconi
                  30 Nov 2020, 13:59

                  @J-Hilk Wow I think you saved my life here, thanks ^^ My app is finally not crashing anymore but I have now an error from my main.qml file : QML StackView: Binding loop detected for property "button". Any idea on why this could happen ?

                  Big thanks.

                  J Offline
                  J Offline
                  J.Hilk
                  Moderators
                  wrote on 30 Nov 2020, 14:03 last edited by
                  #8

                  @kmarconi hard to tell without knowing your qml file content,

                  retranslate does not only reevaluate your text bindings, but all bindings
                  https://doc.qt.io/qt-5/qqmlengine.html#retranslate

                  Note: Due to a limitation in the implementation, this function refreshes all the engine's bindings, not only those that use strings marked for translation. This may be optimized in a future release.
                  

                  so, the bug is probably there from the binging :D


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    kmarconi
                    wrote on 30 Nov 2020, 14:08 last edited by kmarconi
                    #9

                    Here is my main.qml file :

                    Item {
                    id:root
                    visible: true
                    width: 640
                    height: 480

                    property var mainMenu: Menu{rootStack: root}
                    
                    StackView {
                        anchors.fill: parent
                        id: menuStack
                    
                        property var button: hmiclass.button
                        initialItem: mainMenu
                    
                        onButtonChanged: {
                            mainMenu.onButtonPushed(button)
                        }
                    }
                    

                    }

                    EDIT: I need to find where that loop is coming from.. Or to find a patch to refresh only the bindings which are in the translation file.

                    K 2 Replies Last reply 30 Nov 2020, 15:04
                    0
                    • K kmarconi
                      30 Nov 2020, 14:08

                      Here is my main.qml file :

                      Item {
                      id:root
                      visible: true
                      width: 640
                      height: 480

                      property var mainMenu: Menu{rootStack: root}
                      
                      StackView {
                          anchors.fill: parent
                          id: menuStack
                      
                          property var button: hmiclass.button
                          initialItem: mainMenu
                      
                          onButtonChanged: {
                              mainMenu.onButtonPushed(button)
                          }
                      }
                      

                      }

                      EDIT: I need to find where that loop is coming from.. Or to find a patch to refresh only the bindings which are in the translation file.

                      K Offline
                      K Offline
                      kmarconi
                      wrote on 30 Nov 2020, 15:04 last edited by
                      #10

                      @kmarconi Last question : When I check the definition of the retranslate function, it says : Refreshes all binding expressions that use strings marked for translation. What is that "marked" thing and how to apply it ? Thanks

                      J 1 Reply Last reply 30 Nov 2020, 15:23
                      0
                      • K kmarconi
                        30 Nov 2020, 15:04

                        @kmarconi Last question : When I check the definition of the retranslate function, it says : Refreshes all binding expressions that use strings marked for translation. What is that "marked" thing and how to apply it ? Thanks

                        J Offline
                        J Offline
                        J.Hilk
                        Moderators
                        wrote on 30 Nov 2020, 15:23 last edited by
                        #11

                        @kmarconi
                        take a look here:
                        https://doc.qt.io/qt-5/qtquick-internationalization.html


                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                        Q: What's that?
                        A: It's blue light.
                        Q: What does it do?
                        A: It turns blue.

                        K 1 Reply Last reply 30 Nov 2020, 15:29
                        0
                        • J J.Hilk
                          30 Nov 2020, 15:23

                          @kmarconi
                          take a look here:
                          https://doc.qt.io/qt-5/qtquick-internationalization.html

                          K Offline
                          K Offline
                          kmarconi
                          wrote on 30 Nov 2020, 15:29 last edited by
                          #12

                          @J-Hilk Yeah I already been there but every string which needs to be translated are already marked as qsTr so ...

                          J KroMignonK 2 Replies Last reply 30 Nov 2020, 15:31
                          0
                          • K kmarconi
                            30 Nov 2020, 15:29

                            @J-Hilk Yeah I already been there but every string which needs to be translated are already marked as qsTr so ...

                            J Offline
                            J Offline
                            J.Hilk
                            Moderators
                            wrote on 30 Nov 2020, 15:31 last edited by
                            #13

                            @kmarconi said in How can I get the application QmlEngine ?:

                            Yeah I already been there but every string which needs to be translated are already marked as qsTr so ...

                            so, you answered your own question

                            Refreshes all binding expressions that use strings marked for translation. What is that "marked" thing and how to apply it ? Thanks

                            😉


                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            K 1 Reply Last reply 30 Nov 2020, 15:33
                            0
                            • J J.Hilk
                              30 Nov 2020, 15:31

                              @kmarconi said in How can I get the application QmlEngine ?:

                              Yeah I already been there but every string which needs to be translated are already marked as qsTr so ...

                              so, you answered your own question

                              Refreshes all binding expressions that use strings marked for translation. What is that "marked" thing and how to apply it ? Thanks

                              😉

                              K Offline
                              K Offline
                              kmarconi
                              wrote on 30 Nov 2020, 15:33 last edited by
                              #14

                              @J-Hilk Yeah but I thought that maybe there was another thing to do ... I'm stuck now so I'm trying everything I can Haha

                              1 Reply Last reply
                              0
                              • K kmarconi
                                30 Nov 2020, 15:29

                                @J-Hilk Yeah I already been there but every string which needs to be translated are already marked as qsTr so ...

                                KroMignonK Offline
                                KroMignonK Offline
                                KroMignon
                                wrote on 30 Nov 2020, 15:38 last edited by
                                #15

                                @kmarconi said in How can I get the application QmlEngine ?:

                                Yeah I already been there but every string which needs to be translated are already marked as qsTr so ...

                                My way to ensure translation is the define a global Object which handle language changes.
                                This object is exposed to QML with engine->rootContext()->setContextProperty("translation", &myLocalesHandler).

                                This object has a property called emptyString:

                                    Q_PROPERTY(QString emptyString     READ emptyString     NOTIFY languageChanged)
                                ....
                                    QString emptyString() const
                                    {
                                        return QString();
                                    }
                                

                                On language change signal languageChanged() is emitted and in QML I have something like this:

                                Label {
                                    text: qsTr("This is a message") + translation.emptyString
                                }
                                

                                Works great for me, hope this could also helps you.

                                It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                K 1 Reply Last reply 1 Dec 2020, 08:18
                                2
                                • fcarneyF Offline
                                  fcarneyF Offline
                                  fcarney
                                  wrote on 30 Nov 2020, 15:39 last edited by
                                  #16

                                  When I have objects that live in qml space such as a plain QObject, I will make it based upon QQuickItem in order to get the qml engine. I often do this for image providers that provide QImages to qml. I think any QQuick based object should be able to do this.

                                  C++ is a perfectly valid school of magic.

                                  1 Reply Last reply
                                  0
                                  • KroMignonK KroMignon
                                    30 Nov 2020, 15:38

                                    @kmarconi said in How can I get the application QmlEngine ?:

                                    Yeah I already been there but every string which needs to be translated are already marked as qsTr so ...

                                    My way to ensure translation is the define a global Object which handle language changes.
                                    This object is exposed to QML with engine->rootContext()->setContextProperty("translation", &myLocalesHandler).

                                    This object has a property called emptyString:

                                        Q_PROPERTY(QString emptyString     READ emptyString     NOTIFY languageChanged)
                                    ....
                                        QString emptyString() const
                                        {
                                            return QString();
                                        }
                                    

                                    On language change signal languageChanged() is emitted and in QML I have something like this:

                                    Label {
                                        text: qsTr("This is a message") + translation.emptyString
                                    }
                                    

                                    Works great for me, hope this could also helps you.

                                    K Offline
                                    K Offline
                                    kmarconi
                                    wrote on 1 Dec 2020, 08:18 last edited by
                                    #17

                                    @KroMignon Thanks for your help, will try it now. I just have question on your translation class. Where do you emit the signal languageChanged and how do you link it to your function which retranslate the app with the engine ? Thanks !

                                    J 1 Reply Last reply 1 Dec 2020, 08:21
                                    0
                                    • K kmarconi
                                      1 Dec 2020, 08:18

                                      @KroMignon Thanks for your help, will try it now. I just have question on your translation class. Where do you emit the signal languageChanged and how do you link it to your function which retranslate the app with the engine ? Thanks !

                                      J Offline
                                      J Offline
                                      J.Hilk
                                      Moderators
                                      wrote on 1 Dec 2020, 08:21 last edited by
                                      #18

                                      @kmarconi what @KroMignon described was the way you had to go before Qt 5.10

                                      you can take a look at this blog post, I think its rather good:

                                      https://retifrav.github.io/blog/2017/01/04/translating-qml-app/


                                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                      Q: What's that?
                                      A: It's blue light.
                                      Q: What does it do?
                                      A: It turns blue.

                                      K 1 Reply Last reply 1 Dec 2020, 08:54
                                      1
                                      • J J.Hilk
                                        1 Dec 2020, 08:21

                                        @kmarconi what @KroMignon described was the way you had to go before Qt 5.10

                                        you can take a look at this blog post, I think its rather good:

                                        https://retifrav.github.io/blog/2017/01/04/translating-qml-app/

                                        K Offline
                                        K Offline
                                        kmarconi
                                        wrote on 1 Dec 2020, 08:54 last edited by
                                        #19

                                        @J-Hilk Yeah I've seen this post but it's kinda dirty way to retranslate the whole app I think ... I still will try it but I hope to find a way to use the retranslate function properly.

                                        J 1 Reply Last reply 1 Dec 2020, 09:08
                                        0
                                        • K kmarconi
                                          1 Dec 2020, 08:54

                                          @J-Hilk Yeah I've seen this post but it's kinda dirty way to retranslate the whole app I think ... I still will try it but I hope to find a way to use the retranslate function properly.

                                          J Offline
                                          J Offline
                                          J.Hilk
                                          Moderators
                                          wrote on 1 Dec 2020, 09:08 last edited by
                                          #20

                                          @kmarconi
                                          what would you consider a proper retranslate functionality ?

                                          You can either,

                                          • call retranslate() on the QQmlEngine,
                                          • update the strings via the empty string property workaround
                                          • reload the qml file entirely

                                          there are not other ways, at least that I know of


                                          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                          Q: What's that?
                                          A: It's blue light.
                                          Q: What does it do?
                                          A: It turns blue.

                                          K 1 Reply Last reply 1 Dec 2020, 09:18
                                          0

                                          5/38

                                          30 Nov 2020, 13:52

                                          topic:navigator.unread, 33
                                          • Login

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