Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Returning list of objects to QML



  • I have a QList of custom QObjects that I need to return to QML to be displayed in a ListView.

    Q_PROPERTY(QList<MyObject*> myObjects READ getMyObjects)
    
    QList<MyObject*> myObjects;
    
    QList<MyObject*> MyClass::getMyObjects()
    {
        return myObjects;
    }
    

    If I do it like this it seems to be returning a QVariant(QList<MyObject*>) to QML.

    Q_PROPERTY(QList<QObject*> myObjects READ getMyObjects)
    
    QList<MyObject*> myObjects;
    
    QList<QObject*> MyClass::getMyObjects()
    {
        QList<QObject*> objects;
    
        foreach(MyObject* object, myObjects)
            objects.append((QObject*)object);
    
        return objects;
    }
    

    If I do it this way it works fine. Is there a better way to do it without having to make a new QObject list?


  • Moderators

    You can use a model (inherit from QAbstractItemModel or something similar).

    Does QVariant<QList<>> cause you any trouble on QML side? I think it might work better if you returned QVariantList, but not sure.


  • Moderators

    hi @krobinson

    you could simplyfy that a bit, but not by much:

    Q_PROPERTY(QVariant myObjects READ getMyObjects)
    
    QVariant MyClass::getMyObjects()
    {
        return QVariant::fromValue(myObjects);
    }
    

    I'm not sure if myObjects has to be of QList<QObject*> or not, but I usually store my MyObject* in a QObject list and use qobject_cast<MyObject*>(myObjects.at(xyz)); should I need to modify it in c++.



  • Up until this point I have been just storing things in a QList<QObject*> and casting in C++. It works fine that way, I just like having it declared as the actual type. It seems more clear what is going when someone comes back and looks at it. The issue I was having with the QVariant<QList<>> is that if I set a ListViews model to it, it would not work.

    I had an idea that seems to work pretty well. If it has to go as a QList<QObject*> i figured I could write a template function to do it for me.

    template<class T> static QList<QObject *> toQObjectList(QList<T> &list)
    {
        QList<QObject*> qList;
    
        foreach(T item, list)
            qList.append(item);
    
        return qList;
    }
    

    Then I can just return it to QML like this

    return Qml::toQObjectList(remoteDevices);
    

    Seems to be a pretty good solution


  • Moderators

    Looks good indeed. I'd recommend using const QList<T> &list, though, to prevent the container from (potentially) detaching, especially if you migrate to ranged for loop at some point in the future.



  • @sierdzio said in Returning list of objects to QML:

    Looks good indeed. I'd recommend using const QList<T> &list, though, to prevent the container from (potentially) detaching, especially if you migrate to ranged for loop at some point in the future.

    Good call, I will do that. Thanks.


Log in to reply