Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Calling JS functions in loaded components from C++

Calling JS functions in loaded components from C++

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 3 Posters 3.5k 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.
  • A Offline
    A Offline
    Alper
    wrote on 13 May 2016, 18:48 last edited by
    #1

    Hi
    i have main.qml file that it have one JS function in it, i can call the function from C++ by "Q_INVOKABLE" and "QMetaObject::invokeMethod", also i have another Qml file "MyFile.qml" that loaded into "main.qml" with this code:

                var component = Qt.createComponent("file:MyFile.qml");
                var object  = component.createObject(container, {"x": 0, "y": 0});
    

    i cant call functions in MyFile.qml from C++.

    auto root_object = engine->rootObj().first();
    QMetaObject::invokeMethod(rootObj,"jsFunc",Q_RETURN_ARG(QVariant,retVal),Q_ARG(QVariant,conObj));
    

    Error: QMetaObject::invokeMethod: No such method QQuickWindowQmlImpl_QML_35::jsFunc(QVariant)

    pls help

    Thanks in advance

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on 13 May 2016, 20:11 last edited by
      #2

      @Alper said:

      auto root_object = engine->rootObj().first();
      QMetaObject::invokeMethod(rootObj,"jsFunc",Q_RETURN_ARG(QVariant,retVal),Q_ARG(QVariant,conObj));
      

      You're trying to call a function named "jsFunc" that is part of root_object (e.g. your ApplicationWindow) but what you want to do is calling a function of an object that is a child of root_object.

      So first, you need to find the child in the hierarchy and then you can call one of its functions. The easiest way to find children is by giving them a unique objectName in QML, like:

      var object  = component.createObject(mainWindow, {"objectName":"someIdentifier"} );
      

      Then, in C++, you can do this:

      QQuickItem *someItem = m_engine->rootObjects().first()->findChild<QQuickItem*>("someIdentifier");
      QMetaObject::invokeMethod(someItem,"jsFunc");
      
      A 1 Reply Last reply 14 May 2016, 06:44
      1
      • A Offline
        A Offline
        Alper
        wrote on 14 May 2016, 05:07 last edited by
        #3

        @Wieland said:

        mainWindow

        Thanks for your answer.
        So i wrote exactly:

        var object  = component.createObject(container, {"objectName":"someIdentifier"} );
        

        and in C++ i did exactly: (it is after loading component into main window)

        QQuickItem *someItem = m_engine->rootObjects().first()->findChild<QQuickItem*>("someIdentifier");
        QMetaObject::invokeMethod(someItem,"jsFunc");
        

        but it not works.
        Have i replace another thing instead of "objectName" or "someIdentifier" ??

        P 1 Reply Last reply 14 May 2016, 06:42
        0
        • A Alper
          14 May 2016, 05:07

          @Wieland said:

          mainWindow

          Thanks for your answer.
          So i wrote exactly:

          var object  = component.createObject(container, {"objectName":"someIdentifier"} );
          

          and in C++ i did exactly: (it is after loading component into main window)

          QQuickItem *someItem = m_engine->rootObjects().first()->findChild<QQuickItem*>("someIdentifier");
          QMetaObject::invokeMethod(someItem,"jsFunc");
          

          but it not works.
          Have i replace another thing instead of "objectName" or "someIdentifier" ??

          P Offline
          P Offline
          p3c0
          Moderators
          wrote on 14 May 2016, 06:42 last edited by
          #4

          Hi @Alper
          Have you made sure that the exact object is found ?
          What does qDebug() << someItem print ? It should print the objectName someIdentifier with some other properties.

          157

          1 Reply Last reply
          1
          • ? A Former User
            13 May 2016, 20:11

            @Alper said:

            auto root_object = engine->rootObj().first();
            QMetaObject::invokeMethod(rootObj,"jsFunc",Q_RETURN_ARG(QVariant,retVal),Q_ARG(QVariant,conObj));
            

            You're trying to call a function named "jsFunc" that is part of root_object (e.g. your ApplicationWindow) but what you want to do is calling a function of an object that is a child of root_object.

            So first, you need to find the child in the hierarchy and then you can call one of its functions. The easiest way to find children is by giving them a unique objectName in QML, like:

            var object  = component.createObject(mainWindow, {"objectName":"someIdentifier"} );
            

            Then, in C++, you can do this:

            QQuickItem *someItem = m_engine->rootObjects().first()->findChild<QQuickItem*>("someIdentifier");
            QMetaObject::invokeMethod(someItem,"jsFunc");
            
            A Offline
            A Offline
            Alper
            wrote on 14 May 2016, 06:44 last edited by
            #5

            @Wieland
            i solved it!
            i just added a line in MyFile.qml like this:

            Item {
                objectName: "comId"
            ...
            

            main .qml:

            var object  = component.createObject(scr, {"comId":"someId"} );
            

            C++ side:

              QObject *someItem = m_engine->rootObjects().first()->findChild<QObject*>("comId");
              QMetaObject::invokeMethod(someItem,"jsFunc");
            

            Thanks for your help.

            P 1 Reply Last reply 14 May 2016, 06:48
            0
            • A Alper
              14 May 2016, 06:44

              @Wieland
              i solved it!
              i just added a line in MyFile.qml like this:

              Item {
                  objectName: "comId"
              ...
              

              main .qml:

              var object  = component.createObject(scr, {"comId":"someId"} );
              

              C++ side:

                QObject *someItem = m_engine->rootObjects().first()->findChild<QObject*>("comId");
                QMetaObject::invokeMethod(someItem,"jsFunc");
              

              Thanks for your help.

              P Offline
              P Offline
              p3c0
              Moderators
              wrote on 14 May 2016, 06:48 last edited by
              #6

              @Alper Good :)
              But following line doesnot make any sense:
              var object = component.createObject(scr, {"comId":"someId"} );

              You are trying to assign someId to a property named comId which is not present.
              The fact that it worked was due to objectName: "comId" in MyFile.qml which was actually referred when you called findChild.

              157

              A 1 Reply Last reply 14 May 2016, 06:52
              1
              • P p3c0
                14 May 2016, 06:48

                @Alper Good :)
                But following line doesnot make any sense:
                var object = component.createObject(scr, {"comId":"someId"} );

                You are trying to assign someId to a property named comId which is not present.
                The fact that it worked was due to objectName: "comId" in MyFile.qml which was actually referred when you called findChild.

                A Offline
                A Offline
                Alper
                wrote on 14 May 2016, 06:52 last edited by Alper
                #7

                @p3c0

                yes thank you
                it works with:
                var object = component.createObject(scr);
                so can i set dynamic objectName property to component?

                this worked:

                var object  = component.createObject(scr,{"objectName": "newName"});
                
                P 1 Reply Last reply 14 May 2016, 07:02
                0
                • A Alper
                  14 May 2016, 06:52

                  @p3c0

                  yes thank you
                  it works with:
                  var object = component.createObject(scr);
                  so can i set dynamic objectName property to component?

                  this worked:

                  var object  = component.createObject(scr,{"objectName": "newName"});
                  
                  P Offline
                  P Offline
                  p3c0
                  Moderators
                  wrote on 14 May 2016, 07:02 last edited by p3c0
                  #8

                  @Alper

                  so can i set dynamic objectName property to component?

                  Yes. @Wieland's suggestion was correct.
                  It seems that you passed the wrong parent earlier.

                  157

                  1 Reply Last reply
                  1

                  2/8

                  13 May 2016, 20:11

                  topic:navigator.unread, 6
                  • Login

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