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. Issue passing QML object to C++ QVariantMap
Forum Updated to NodeBB v4.3 + New Features

Issue passing QML object to C++ QVariantMap

Scheduled Pinned Locked Moved Solved QML and Qt Quick
10 Posts 3 Posters 1.9k Views 2 Watching
  • 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.
  • J Offline
    J Offline
    Josh
    wrote on last edited by
    #1

    Hi,

    I'm getting an error when trying to pass a simple QML object to a C++ function as a QVariantMap.

    My CPPClass has a member:

    Q_INVOKABLE cppFunc(QVariantMap obj) {}

    Over in QML I have a ListModel that has elements like:

    { foo: 1, bar: 2, baz: 3}

    I want to pull items from the list model and pass them to cppFunc. Like this:

    var obj =listModel.get(0)
    
    cppClass.cppFunc(obj)
    

    Unfortunately, this produces the following runtime error:

    Passing incompatible arguments to C++ functions from JavaScript is dangerous and deprecated.
    

    However, if I create a new object based on the obj from the listModel then it works:

    var obj =listModel.get(0)
    var copyOfObj = {foo: obj.foo, bar: obj.bar, baz: obj.baz}
    cppClass.cppFunc(copyOfObj)
    

    According to the debugger obj and copyOfObj are both valid and exactly the same.

    Can anyone explain why it's necessary to make this copy of a listModel item before passing it to C++?

    Using Qt 5.12.5.

    Thanks!

    raven-worxR 2 Replies Last reply
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      Hi @Josh, and welcome!

      I'm not sure what's causing this behaviour, but:

      • What does console.log(typeof obj) and console.log(typeof copyOfObj) show?
      • The code which produces that error message is at https://code.woboq.org/qt5/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp.html#_ZL10CallMethodRK18QQmlObjectOrGadgetiiiPiPN3QV415ExecutionEngineEPNS3_8CallDataEN11QMetaObject4CallE -- Did you also get a message, "Could not convert argument X at Y"?

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      2
      • J Josh

        Hi,

        I'm getting an error when trying to pass a simple QML object to a C++ function as a QVariantMap.

        My CPPClass has a member:

        Q_INVOKABLE cppFunc(QVariantMap obj) {}

        Over in QML I have a ListModel that has elements like:

        { foo: 1, bar: 2, baz: 3}

        I want to pull items from the list model and pass them to cppFunc. Like this:

        var obj =listModel.get(0)
        
        cppClass.cppFunc(obj)
        

        Unfortunately, this produces the following runtime error:

        Passing incompatible arguments to C++ functions from JavaScript is dangerous and deprecated.
        

        However, if I create a new object based on the obj from the listModel then it works:

        var obj =listModel.get(0)
        var copyOfObj = {foo: obj.foo, bar: obj.bar, baz: obj.baz}
        cppClass.cppFunc(copyOfObj)
        

        According to the debugger obj and copyOfObj are both valid and exactly the same.

        Can anyone explain why it's necessary to make this copy of a listModel item before passing it to C++?

        Using Qt 5.12.5.

        Thanks!

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by raven-worx
        #3

        @Josh
        thats because ListModel returns a object type and not a JSON object. Which i assume results in a QJSValue on the C++ side (can easily be checked by changing the signature to take a QVariant and output the passed parameter with qDebug for example)

        https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/qmlmodels/qqmllistmodel.cpp?h=dev#n2550

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        J 1 Reply Last reply
        3
        • J Josh

          Hi,

          I'm getting an error when trying to pass a simple QML object to a C++ function as a QVariantMap.

          My CPPClass has a member:

          Q_INVOKABLE cppFunc(QVariantMap obj) {}

          Over in QML I have a ListModel that has elements like:

          { foo: 1, bar: 2, baz: 3}

          I want to pull items from the list model and pass them to cppFunc. Like this:

          var obj =listModel.get(0)
          
          cppClass.cppFunc(obj)
          

          Unfortunately, this produces the following runtime error:

          Passing incompatible arguments to C++ functions from JavaScript is dangerous and deprecated.
          

          However, if I create a new object based on the obj from the listModel then it works:

          var obj =listModel.get(0)
          var copyOfObj = {foo: obj.foo, bar: obj.bar, baz: obj.baz}
          cppClass.cppFunc(copyOfObj)
          

          According to the debugger obj and copyOfObj are both valid and exactly the same.

          Can anyone explain why it's necessary to make this copy of a listModel item before passing it to C++?

          Using Qt 5.12.5.

          Thanks!

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @Josh
          i honestly dont know if it works but try:

          var obj = JSON.parse(JSON.stringify(model.get(0)))
          

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • J Offline
            J Offline
            Josh
            wrote on last edited by
            #5

            @JKSH Yes, also prints "Could not convert argument 1 at".

            Console.log(typeof obj) & console.log(copyOfObj) show both as "object"

            qml: object
            qml: object
            
            1 Reply Last reply
            0
            • raven-worxR raven-worx

              @Josh
              thats because ListModel returns a object type and not a JSON object. Which i assume results in a QJSValue on the C++ side (can easily be checked by changing the signature to take a QVariant and output the passed parameter with qDebug for example)

              https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/qmlmodels/qqmllistmodel.cpp?h=dev#n2550

              J Offline
              J Offline
              Josh
              wrote on last edited by Josh
              #6

              @raven-worx said in Issue passing QML object to C++ QVariantMap:

              @Josh
              thats because ListModel returns a object type and not a JSON object. Which i assume results in a QJSValue on the C++ side (can easily be checked by changing the signature to take a QVariant and output the passed parameter with qDebug for example)

              https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/qmlmodels/qqmllistmodel.cpp?h=dev#n2550

              The original obj and copyOfObj are both "object" to QML, according to debugger and typeof.

              On the C++ side, copyOfObj gets successfully passed into the QVariantMap.

              This does work, but it's still generating a copy.

              JSON.parse(JSON.stringify(entry)
              

              It seems like it should work without the copy. According to the docs:

              The QML engine provides automatic type conversion between QVariantList and JavaScript arrays, and between QVariantMap and JavaScript objects.
              

              and

              Similarly, if a C++ type uses a QVariantList or QVariantMap type for a property type or method parameter, the value can be created as a JavaScript array or object in QML, and is automatically converted to a QVariantList or QVariantMap when it is passed to C++.
              

              Am I reading this wrong?

              Thanks for your help!

              raven-worxR 1 Reply Last reply
              0
              • J Josh

                @raven-worx said in Issue passing QML object to C++ QVariantMap:

                @Josh
                thats because ListModel returns a object type and not a JSON object. Which i assume results in a QJSValue on the C++ side (can easily be checked by changing the signature to take a QVariant and output the passed parameter with qDebug for example)

                https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/qmlmodels/qqmllistmodel.cpp?h=dev#n2550

                The original obj and copyOfObj are both "object" to QML, according to debugger and typeof.

                On the C++ side, copyOfObj gets successfully passed into the QVariantMap.

                This does work, but it's still generating a copy.

                JSON.parse(JSON.stringify(entry)
                

                It seems like it should work without the copy. According to the docs:

                The QML engine provides automatic type conversion between QVariantList and JavaScript arrays, and between QVariantMap and JavaScript objects.
                

                and

                Similarly, if a C++ type uses a QVariantList or QVariantMap type for a property type or method parameter, the value can be created as a JavaScript array or object in QML, and is automatically converted to a QVariantList or QVariantMap when it is passed to C++.
                

                Am I reading this wrong?

                Thanks for your help!

                raven-worxR Offline
                raven-worxR Offline
                raven-worx
                Moderators
                wrote on last edited by
                #7

                @Josh said in Issue passing QML object to C++ QVariantMap:

                It seems like it should work without the copy. According to the docs:
                The QML engine provides automatic type conversion between QVariantList and JavaScript arrays, and between QVariantMap and JavaScript objects.

                But the returned object is actually of the type QObject.
                As i said, try the approach where you change the parameter to a QVariant and check its actual type.

                IMHO the docs might be a bit misleading and should read "...and between QVariantMap and JSON objects."

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                J 1 Reply Last reply
                3
                • raven-worxR raven-worx

                  @Josh said in Issue passing QML object to C++ QVariantMap:

                  It seems like it should work without the copy. According to the docs:
                  The QML engine provides automatic type conversion between QVariantList and JavaScript arrays, and between QVariantMap and JavaScript objects.

                  But the returned object is actually of the type QObject.
                  As i said, try the approach where you change the parameter to a QVariant and check its actual type.

                  IMHO the docs might be a bit misleading and should read "...and between QVariantMap and JSON objects."

                  J Offline
                  J Offline
                  Josh
                  wrote on last edited by
                  #8

                  @raven-worx said in Issue passing QML object to C++ QVariantMap:

                  @Josh said in Issue passing QML object to C++ QVariantMap:

                  It seems like it should work without the copy. According to the docs:
                  The QML engine provides automatic type conversion between QVariantList and JavaScript arrays, and between QVariantMap and JavaScript objects.

                  But the returned object is actually of the type QObject.
                  As i said, try the approach where you change the parameter to a QVariant and check its actual type.

                  IMHO the docs might be a bit misleading and should read "...and between QVariantMap and JSON objects."

                  You are correct. When passed as a QVariant the original obj is a QObject*, the copy is a QJSValue.

                  So copying/converting to a QJSValue is the right way to do this?

                  Yes the docs on this issue are confusing.

                  Thanks for your help.

                  raven-worxR 1 Reply Last reply
                  0
                  • J Josh

                    @raven-worx said in Issue passing QML object to C++ QVariantMap:

                    @Josh said in Issue passing QML object to C++ QVariantMap:

                    It seems like it should work without the copy. According to the docs:
                    The QML engine provides automatic type conversion between QVariantList and JavaScript arrays, and between QVariantMap and JavaScript objects.

                    But the returned object is actually of the type QObject.
                    As i said, try the approach where you change the parameter to a QVariant and check its actual type.

                    IMHO the docs might be a bit misleading and should read "...and between QVariantMap and JSON objects."

                    You are correct. When passed as a QVariant the original obj is a QObject*, the copy is a QJSValue.

                    So copying/converting to a QJSValue is the right way to do this?

                    Yes the docs on this issue are confusing.

                    Thanks for your help.

                    raven-worxR Offline
                    raven-worxR Offline
                    raven-worx
                    Moderators
                    wrote on last edited by
                    #9

                    @Josh said in Issue passing QML object to C++ QVariantMap:

                    So copying/converting to a QJSValue is the right way to do this?

                    this or JSON.parse(JSON.stringify(entry)

                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                    If you have a question please use the forum so others can benefit from the solution in the future

                    J 1 Reply Last reply
                    2
                    • raven-worxR raven-worx

                      @Josh said in Issue passing QML object to C++ QVariantMap:

                      So copying/converting to a QJSValue is the right way to do this?

                      this or JSON.parse(JSON.stringify(entry)

                      J Offline
                      J Offline
                      Josh
                      wrote on last edited by
                      #10

                      @raven-worx That works for me. Thanks for clarifying this issue for me.

                      1 Reply Last reply
                      0

                      • Login

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