Passing c++ array to QML



  • Hi !

    I have a c++ class with private : int parameterInt[64];

    How can i access this array from my QML ? (for exemple : to create ListElements for my ListView )

    I know for a simple 'int myValue' I can crate Q_PROPERTY(...) to access it from QML, but in case of arrays how to do this please ?

    Thx

    LA



  • Hi .. i am new on qml..
    but i know method:

    http://qmlbook.github.io/en/ch12/index.html & xml & javacript..
    I self have tested to auto generate javascript with tool cmake...
    after is the proprity metod from evry item:

     model: ["Enterprise", "Columbia", "Challenger", "Discovery", "Endeavour", "Atlantis"]
    
    

    http://qmlbook.github.io/en/ch06/index.html
    I prefer javascript is so fast.. and i must not think brower crosscompatibility ... :-)

    not forget json:

    Component.onCompleted: {
            var JsonString = '{"a":"A whatever, run","b":"B fore something happens"}';
            var JsonObject= JSON.parse(JsonString);
    
            //retrieve values from JSON again
            var aString = JsonObject.a;
            var bString = JsonObject.b;
    
            console.log(aString);
            console.log(bString);
        }
    

  • Moderators

    @LeLev
    if you do not want to copy the array-data take a look at this example. In specific the usage of QQmlListProperty

    Otherwise the simplest solution would be to define a property of the type QList<int> and convert the array to QList on the fly in the read method. QList is automatically translated for QML then.



  • @LeLev I also wonder why do you need a bare array at all. In all articles etc. which I have read about C++ lately it is told that in modern C++ style higher level constructions are preferred to low-level C-based constructions. Unless you have a real perfomance need which you have actually tested for speed/memory you could use QList directly. It's highly optimized anyways.



  • Thx very much guys i will try with QList



  • Hi again,

    i have created Q_Property like this:

    Q_PROPERTY(QList<int> _UInt32_list READ get_UInt32_list NOTIFY _UInt32_listChanged)

    i have my private QList<int> _UInt32_list;

    getter:
    QList<int> _UInt32_list(){
    return _UInt32_list;
    }

    c++ side iIm initializing my QList without problemes.

    To access from QML :

    Client client;
    engine.rootContext()->setContextProperty("cl",&client);

    but when i try to access it from QML with ' cl._UInt32_list[5]' it telling me that '_UInt32_list' is not defined ..
    "Cannot read property '0' of undefined"

    My other getters are working with scalar things ..



  • @LeLev Find out first what is actually undefined. Add javascript console.log output somewhere which print cl and cl._Uint32_list or check with QML debugger. You didn't give us any context, we can't know if you only made a guess that "Cannot read property '0' of undefined" would mean that the list property isn't defined, or do you actually know that it is so...



  • If you write "cl._UInt32_list[5]" and it tell you "Cannot read property '0' of undefined it means that "cl._UInt32_list" is not defined ..

    Im just wondering about how to pass a simple array or list or variant containing ints from cpp to QML this is simple no ?



  • "cl" is defined ! because as i said :

    "My other getters are working with scalar properties."

    I only have this probleme with QList property ! if i do same thing with just a Q_Property QString or Simple Int it works !

    So yes "cl" is defined but not cl._Uint32_list


  • Moderators

    @LeLev
    please try to name the property starting with a lower case character and probably best without any special characters.
    I currently can't recall the required naming conventions for QML properties, but it's worth a try.

    You may also read this.

    Edit:
    Here you go:

    Property names must begin with a lower case letter and can only contain letters, numbers and underscores.



  • @raven-worx It is lower case already in my real code it was 'parameter_UInt32_list' so its ok .. and i dont have special char



  • and i made an other post bcz this one not helping me at all and it is to long if new persons come ..



  • @LeLev said in Passing c++ array to QML:

    @raven-worx It is lower case already in my real code it was 'parameter_UInt32_list' so its ok .. and i dont have special char

    I don't mean to be rude, and sorry for you if it's taking longer than you would like to get an answer, but posting code which is not your actual code makes it really difficult for people to reply and help you properly.... It's a general point in code-posting that's very important.


  • Moderators

    @LeLev said in Passing c++ array to QML:

    and i made an other post bcz this one not helping me at all and it is to long if new persons come ..

    well we are working on a solution here no?
    Double posts are not welcome in any forum...

    @LeLev said in Passing c++ array to QML:

    @raven-worx It is lower case already in my real code it was 'parameter_UInt32_list' so its ok .. and i dont have special char

    When you expect proper help you should post you actual code (or at least portions of it) instead letting us hunt down a fictional issue in the end.

    Please post your whole code. Header file is enough.
    We also know that you've added a context property....good.
    You do set the context property before you load the QML component? Probably it's also the best to show the QML section where you access the list property.



  • Sorry .. 2 days i'm on this ... i changed little bit code to be more concise/ clear but i agree in this case i added more confusion..

    So yes my property starts with lower case and no special char.

    I was looking to your link concerning Data Conversions (http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#sequence-type-to-javascript-array) but i dont have more elements with this..

    ..So complicated to do a very simple thing...



  • @raven-worx said in Passing c++ array to QML:

    You do set the context property before you load the QML component?

    one more time, as i said "My other getters are working with scalar properties." with string OK, with int OK, with real OK ! So yes i have set the context property before i load the QML as everything is working as expected except QList<int>





  • here the exact code .. :

    Q_PROPERTY(QList<int> parameterUInt32list READ getparameterUInt32list NOTIFY parameterUInt32listChanged)

    .....
    private:
    QList<int> parameterUInt32list;
    .....
    public :
    QList<int> getparameterUInt32list(){
    return parameterUInt32list;
    }
    ....
    main.cpp >> engine.rootContext()->setContextProperty("cl",&clientW);

    QML : console.log(typeof(cl.parameterUInt32list)) // log is : Object
    console.log(typeof(cl.parameterUInt32list[1])) // log is : Undefined



  • @JNBarchan i already saw this.Not sure this is whant I need .. they want List of objects. I want list of int


  • Moderators

    @LeLev said in Passing c++ array to QML:

    console.log(typeof(cl.parameterUInt32list[1])) // log is : Undefined

    so you are trying to access the 2nd element from the list and check it's type.
    Where is this list filled with values?

    Place the following before this log line and post what it returns:

    console.log( cl.parameterUInt32list.length )
    


  • @LeLev
    OK, I get that. What about http://doc.qt.io/qt-5/qtqml-cppintegration-data.html, topic "Sequence Type to JavaScript Array"? That states it includes QList<int>!



  • Thx but this is the link raven-worx gave me..

    It says "here are two ways in which such sequences can be exposed to QML: as a Q_PROPERTY of the given sequence type; or as the return type of a Q_INVOKABLE method. "

    i did it with Q_PROPERTY but it's not working. I realy need an exemple because i spent more than 6-7 houres on this.. ^^

    I will try the other way.



  • @LeLev
    OK, sorry, I'll butt out now! I think @raven-worx is the expert here!



  • @JNBarchan :D np np thx



  • So i have tryed with Q_INVOKABLE :

    c++ ( just test ) : Q_INVOKABLE int getParams () {
    return 10;
    }

    QML : i can do (after set the context property) : console.log(c.getParams()) // its ok

    Now i i just change return type to QList<int> :
    Q_INVOKABLE QList<int> getParams () {
    return parameterUInt32list ;
    }

    QML console.log(c.getParams()) // undefined

    So clearly there is a special thing to do to be able to pass a QList to QML ... this realy annoyed me.

    thx in any cases



  • @LeLev
    OK, I know I said I'd butt out, but I really think I've got your solution now!
    Look at https://stackoverflow.com/a/15642120/489865.

    If you need to exchange a QStringList or a QList or anything that is an array of one of the basic types supported by QML, the easiest way to do it is to use QVariant on the C++ side

    I think the poster is saying you should try this even though the docs claim "there is transparent support for QList<int> ".

    At least, it's worth a try, if you're saying what you presently have still does not work ('coz you're saying with Q_INVOKABLE you're still getting "undefined", so you don't have a solution, or have I misunderstood?).... Also, it might help you/others for other types.



  • @JNBarchan Thx ! i think this is the solution !



  • @JNBarchan thx ! it worked with QVariant



  • @LeLev said in Passing c++ array to QML:

    @JNBarchan thx ! it worked with QVariant

    Yay! Really pleased for you :)

    So do you think the gist is: although it seems it ought to be that Qlist<int> "should work transparently", you found that it did not but the generic way of wrapping in a QVariant did work?



  • @JNBarchan yes exactly.

    here is the function :) :

    so c++ class (Client) side i have a QVariant like : myQVariant[0,1,2,3,4...]

    main.cpp : Client client; engine.rootContext()->setContextProperty("client",&client);

    and qml :

    function createListUInt32(){
    
        var el = client.getParamUInt32();  // PUBLIC SLOT return myQVariant
    
    
        for(var i in el){
    
            var data = {'val':el[i]}; 
            mod.append(data)  // and 'mod' is qml listModel
        }
    }
    

    THx again :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.