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

Passing a QList of structs to qml



  • I have a struct with the form

    struct DataEntry{
        Q_GADGET
        Q_PROPERTY(QString title READ title WRITE setTitle)
        Q_PROPERTY(QDate date READ date WRITE setDate )
        Q_PROPERTY(QTime time READ time WRITE setTime )
        Q_PROPERTY(QString note READ note WRITE setNote )
        Q_PROPERTY(QString important READ important WRITE setImportant )
    public:
        QString title()const{
            return m_title;
        }
        QDate date() const{
            return m_date;
        }
        QTime time() const{
            return m_time;
        }
        QString note()  const{
            return m_note;
        }
        QString important() const{
            return m_important;
        }
    public slots:
        void setTitle(QString title){
            if(m_title == title){
                return;
            }
            m_title = title;
            //emit titleChanged(title);
        }
        void setDate(QDate date){
            if(m_date == date){
                return;
            }
            m_date = date;
            //emit dateChanged(date);
        }
        void setTime(QTime time){
            if(m_time == time){
                return;
            }
            m_time = time;
            //emit  timeChanged(time);
        }
        void setNote(QString note){
            if(m_note == note){
                return;
            }
            m_note = note;
            //emit noteChanged(note);
        }
        void setImportant(QString important){
            if(m_important == important){
                return;
            }
            m_important = important;
            //emit importantChanged(important);
        }
    /*signals:
        void titleChanged(QString arg);
        void dateChanged(QDate arg);
        void timeChanged(QTime arg);
        void noteChanged(QString arg);
        void importantChanged(QString arg);*/
    private:
        QString m_title;
        QDate m_date;
        QTime m_time;
        QString m_note;
        QString m_important;
    
    };
    

    Then A FileIo class to read and write to a file with the following form

    class FileIO: public QObject
    {
        Q_OBJECT
        Q_DISABLE_COPY(FileIO)
        Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
        Q_PROPERTY(QList<DataEntry> memberList READ memberList WRITE setMemberList NOTIFY memberListChanged)
        Q_PROPERTY(DataEntry member READ member WRITE setMember NOTIFY memberChanged)
    public:
        FileIO(QObject *parent = nullptr);
        ~FileIO();
        Q_INVOKABLE void read();
        Q_INVOKABLE void write();
        QUrl source() const;
        QList<DataEntry>memberList()const;
        DataEntry member()const;
    public slots:
        void setSource(QUrl source);
        void setMemberList(QList<DataEntry> memberList);
        void setMember(DataEntry member);
    signals:
        void sourceChanged(QUrl arg);
        void memberListChanged(QList<DataEntry> memberList);
        void memberChanged(DataEntry member);
    private:
        QUrl m_source;
        QList<DataEntry> m_memberList;
        DataEntry m_member;
    };
    
    

    I have a qml file which uses the following listView

    ListView{
            Component{
                id: listDelegate
                Rectangle{
                    width: root.width
                    height: 40
                    border.color: Qt.lighter("blue")
                    Rectangle{
                        id: importantRect
                        anchors.left: parent.left
                        anchors.verticalCenter: parent.verticalCenter
                        width: 30
                        height: 30
                        radius: 15
                        color: function(){
                                if(important == "Very"){
                                    return "red"
                                }else if(important == "Moderate"){
                                    return "yellow"
                                }else{
                                    return "green"
                                }
                               }
                    }
                    Text {
                        id: nameText
                        text: title
                        anchors.left: importantRect.right
                        anchors.top: parent.top
                        color: "black"
                        font.pixelSize: 20
                        style: Text.Outline
                        styleColor: "lightgray"
                        elide: Text.ElideRight
                        Component.onCompleted: {
                            console.log(nameText + "from qml")
                        }
                    }
                    Text {
                        id: dateText
                        text: date.toLocaleString(Qt.locale(),"dd:mm:yy")
                        anchors.left: importantRect.right
                        anchors.top: nameText.bottom
                        color: "grey"
                        font.pixelSize: 15
                        style: Text.Sunken
                        styleColor: "lightgray"
                    }
                    Text{
                        id: timeText
                        text: time.toLocaleString(Qt.locale(),"h:m a")
                        anchors.left: dateText.right
                        anchors.top: nameText.bottom
                        color: "grey"
                        font.pixelSize: 15
                        style: Text.Sunken
                        styleColor: "lightgray"
                    }
                }
            }
            model: io.memberList
            delegate: listDelegate
            anchors.fill: parent
            Component.onCompleted: {
                console.log(model.title)
            }
        }
    
    FileIO{
                id: io
        }
    

    The io.memberList is meant to return a QList and use it to serve as a model for the ListView but this does not work, Is there a different way of using QLists to initialize models?


  • Lifetime Qt Champion

    Hi
    As far as i know, ListView only understands
    QStringList, QList<QObject*> or a QAbstractItemModel for a model.
    Not QList of some struct.

    So i think your best option is like the
    class AnimalModel : public QAbstractListModel
    as shown in
    https://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html

    Disclaimer. I could be wrong and you might be able to expose the Qlist directly so
    wait a day or more to see if anyone has other suggestion. :=)



  • Alright, Thank you,
    I will start working on the QAbstractItemModel example incase it's not possible


  • Lifetime Qt Champion

    @abdulmueez
    Well you could also change DataEntry into being QObject based and try
    a QList<DataEntry*> as model input but the ItemModel gives automatic updates of the view if data changes and overall just might work better.



  • Initially, Dataentry was a class inheriting from QObject but I was having problems using the copy constructor so, I changed it to a struct


  • Lifetime Qt Champion

    @abdulmueez
    Ok, QObjects are not copyable by design
    so it has to be via pointer when putting them in a list.



  • Okay and also one more question, If I want to use the DataEntry as a QObject child, Is the property also a pointer. i.e

    Q_PROPERTY(DataEntry* member READ member WRITE setMember NOTIFY memberChanged)
    
    

Log in to reply