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. QVarianList in QVariantList flattening when passing into QML/JavaScript like Array in Array. Why?
Forum Updated to NodeBB v4.3 + New Features

QVarianList in QVariantList flattening when passing into QML/JavaScript like Array in Array. Why?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
10 Posts 3 Posters 2.3k 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.
  • B Offline
    B Offline
    bogong
    wrote on 23 Mar 2019, 10:32 last edited by bogong
    #1

    Hello all!

    I need to get array-in-array into Javascript from CPP. I am trying to get from QVarianList in QVariantList in CPP

    QVariantList test::returnArray(void) {
    
    	QVariantList vResult;
    	QVariantList vValue;
    
    	vValue.append(1);
    	vValue.append("two");
    	vValue.append(true);
    	vResult.insert(vResult.size(),vValue);
    
    	vValue.append(2);
    	vValue.append("two");
    	vValue.append(true);
    	vResult.insert(vResult.size(),vValue);
    
    	vValue.append(3);
    	vValue.append("two");
    	vValue.append(true);
    	vResult.insert(vResult.size(),vValue);
    
    	return vResult;
    }
    

    It's became flatten and duplicated. Result is:

    qml: [1,two,true,1,two,true,2,two,true,1,two,true,2,two,true,3,two,true]
    

    How to make something like this:

    qml: [[1,"two",true],[2,"two",true],[3,"two",true]]
    
    J 1 Reply Last reply 23 Mar 2019, 10:50
    0
    • B bogong
      23 Mar 2019, 10:32

      Hello all!

      I need to get array-in-array into Javascript from CPP. I am trying to get from QVarianList in QVariantList in CPP

      QVariantList test::returnArray(void) {
      
      	QVariantList vResult;
      	QVariantList vValue;
      
      	vValue.append(1);
      	vValue.append("two");
      	vValue.append(true);
      	vResult.insert(vResult.size(),vValue);
      
      	vValue.append(2);
      	vValue.append("two");
      	vValue.append(true);
      	vResult.insert(vResult.size(),vValue);
      
      	vValue.append(3);
      	vValue.append("two");
      	vValue.append(true);
      	vResult.insert(vResult.size(),vValue);
      
      	return vResult;
      }
      

      It's became flatten and duplicated. Result is:

      qml: [1,two,true,1,two,true,2,two,true,1,two,true,2,two,true,3,two,true]
      

      How to make something like this:

      qml: [[1,"two",true],[2,"two",true],[3,"two",true]]
      
      J Offline
      J Offline
      JonB
      wrote on 23 Mar 2019, 10:50 last edited by
      #2

      @bogong
      I'm not sure, but have a look at

      https://doc.qt.io/qt-5/qtqml-cppintegration-data.html, Sequence Type to JavaScript Array

      https://doc-snapshots.qt.io/qt5-dev/qtqml-cppintegration-data.html, QVariantList and QVariantMap to JavaScript Array and Object

      ?

      B 1 Reply Last reply 23 Mar 2019, 10:52
      0
      • J JonB
        23 Mar 2019, 10:50

        @bogong
        I'm not sure, but have a look at

        https://doc.qt.io/qt-5/qtqml-cppintegration-data.html, Sequence Type to JavaScript Array

        https://doc-snapshots.qt.io/qt5-dev/qtqml-cppintegration-data.html, QVariantList and QVariantMap to JavaScript Array and Object

        ?

        B Offline
        B Offline
        bogong
        wrote on 23 Mar 2019, 10:52 last edited by
        #3

        @JonB Thanks for reply. I've seen all of it. There are all OK when one-dimension array/QVarinatList. When I am trying to pass 2/3/4/n-dimensions array it's flattening. I need to avoid it.

        J 1 Reply Last reply 23 Mar 2019, 11:00
        0
        • B bogong
          23 Mar 2019, 10:52

          @JonB Thanks for reply. I've seen all of it. There are all OK when one-dimension array/QVarinatList. When I am trying to pass 2/3/4/n-dimensions array it's flattening. I need to avoid it.

          J Offline
          J Offline
          JonB
          wrote on 23 Mar 2019, 11:00 last edited by JonB
          #4

          @bogong
          Yes, I do understand what you want, and that you're finding it gets flattened. The problem may be that it says things like QML supports, say, QList<int> but not QList<QVariant>. You might test with that to verify it is the (nested) QVariantList which is the problem, it would work with QList<int> instead? (You should of course verify back in C++ that your constructed list is indeed what we understand it to be, and not already flattened.)

          Trying to look for a workaround if you cannot solve/don't get a better answer, e.g. maybe https://doc.qt.io/qt-5/json.html would allow you to achieve it via JSON (https://stackoverflow.com/questions/41900383/parsing-json-in-qml)?

          B 1 Reply Last reply 23 Mar 2019, 11:38
          1
          • J JonB
            23 Mar 2019, 11:00

            @bogong
            Yes, I do understand what you want, and that you're finding it gets flattened. The problem may be that it says things like QML supports, say, QList<int> but not QList<QVariant>. You might test with that to verify it is the (nested) QVariantList which is the problem, it would work with QList<int> instead? (You should of course verify back in C++ that your constructed list is indeed what we understand it to be, and not already flattened.)

            Trying to look for a workaround if you cannot solve/don't get a better answer, e.g. maybe https://doc.qt.io/qt-5/json.html would allow you to achieve it via JSON (https://stackoverflow.com/questions/41900383/parsing-json-in-qml)?

            B Offline
            B Offline
            bogong
            wrote on 23 Mar 2019, 11:38 last edited by
            #5

            @JonB JSON - might be solution. But 2 additional conversion, from CPP to JSON-string and from JSON-string to JavaScript data. It might be very expensive for resources in case of big array.

            1 Reply Last reply
            0
            • B Offline
              B Offline
              bogong
              wrote on 25 Mar 2019, 08:54 last edited by bogong
              #6

              I've tested:

              • return like Q_PROPERTY(QJsonObject array READ array CONSTANT) in registered QML component
              • return like registered object via QVarinatList
              • return like registered object via QVariantMap

              In every way it's flattening multi-dimensional arrays in one-dimensional.
              The only way that I found is to create QString within JSON-String and parse it in QML JavaScript like JSON.parse(String). Look below on console log from pure CPP and QML:

              QJsonObject({"1":1,"2":2,"array":[[1,"2",true],[1,"2",true],[1,"2",true]]})
              qml: [1,2,true,1,2,true,1,2,true]
              

              But there are 2 additional senseless data conversions. In case of big portion of data in array (I've been testing it in 2000 elements and every element contain inner array of 17 element) this solution slowing down application hardly.

              1 Reply Last reply
              0
              • GrecKoG Offline
                GrecKoG Offline
                GrecKo
                Qt Champions 2018
                wrote on 25 Mar 2019, 09:03 last edited by
                #7

                What about a QJSValue property type?

                B 2 Replies Last reply 25 Mar 2019, 09:55
                0
                • GrecKoG GrecKo
                  25 Mar 2019, 09:03

                  What about a QJSValue property type?

                  B Offline
                  B Offline
                  bogong
                  wrote on 25 Mar 2019, 09:55 last edited by
                  #8

                  @GrecKo What "what about"?

                  1 Reply Last reply
                  0
                  • GrecKoG GrecKo
                    25 Mar 2019, 09:03

                    What about a QJSValue property type?

                    B Offline
                    B Offline
                    bogong
                    wrote on 25 Mar 2019, 10:11 last edited by bogong
                    #9

                    @GrecKo There are another trouble - architectural. The JS Engine should be one for whole application and It's starting from main:

                    int main(int Counter, char *Arguments[]) {
                    
                    	QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                    	QGuiApplication Application(Counter, Arguments);
                    
                    	qmlRegisterType<CPPCustomQMLComponent>("Examples.cutomQMLComponent",1,0,"CustomComponent");
                    
                    	QQmlApplicationEngine Engine;
                    	
                    	Engine.load(QUrl(Main));
                    	if (Engine.rootObjects().isEmpty())
                    		return -1;
                    
                    	return Application.exec();
                    }
                    

                    For the case of dynamic usage it might be very complicated every time when I need simple multi-dimensional array to register it in global engine. I am trying to get it from non global object:

                    JSValue can't be reassigned to another engine.
                    qrc:/main.qml:28: TypeError: Cannot read property 'array' of undefined
                    

                    From:

                    QJSEngine oEngine;
                    QJSValue vArray = oEngine.newArray(3);
                    QJSValue vArrayInner = oEngine.newArray(3);
                    vArrayInner.setProperty(0,1);
                    vArrayInner.setProperty(1,"string");
                    vArrayInner.setProperty(2,true);
                    vArray.setProperty(0,vArrayInner);
                    vArray.setProperty(1,vArrayInner);
                    vArray.setProperty(2,vArrayInner);
                    
                    return vArray;
                    
                    1 Reply Last reply
                    0
                    • B Offline
                      B Offline
                      bogong
                      wrote on 17 Sept 2019, 12:41 last edited by bogong 11 Jan 2019, 15:55
                      #10

                      The cause of trouble found. There are difference between methods "append" and "insert". When you using "append" - it's flattening, when using "insert" - everything OK. The full featured example published here.

                      Beside all of it there are the BUG in QML JS console.log()

                      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