Zett
Zett

Reputation: 23

How to display data added via another class in C ++ to ListView, QML?

I need to present all the data in the QLinkedList container (this was given by the task). I created two classes, DataObject for my delegates in ListView, Glav for container with DataObject objects. I have a button on which I add data to the container (the addItem function in the Glav class). The data is added but not displayed in the ListView. How to display them? I tried it through signals, it didn't work. Here is the complete code of the project.

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QStringListModel>
#include <QQmlContext>
#include <QLinkedList>
#include <QQuickView>

#include <container.h>
#include <dataobject.h>
#include "glav.h"
//#include <container.cpp>

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    qmlRegisterUncreatableType<tile::Glav>( "Tile", 1, 0, "DataItem", "interface" );

    qmlRegisterType<tile::Glav>( "Tile", 1, 0, "Glav");

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

main.qml

import QtQuick 2.12
import QtQuick.Controls 2.5
//import App 1.0
import Tile 1.0

ApplicationWindow {
    width: 640
    height: 480
    visible: true
    title: qsTr("Scroll")

//    Container {
//        id: container
//    }

    Glav {
        id: glav
    }


    Row {
        id: buttons
        spacing: 20
        padding: 10
        anchors.horizontalCenter: parent.horizontalCenter

        RoundButton {
            padding: 20
            text: "add item"
            onClicked: {

                glav.addItem()
                listView.currentIndex = -1
            }

    }

    Connections{
    target: myModelObjectWhichWasSetAsContextProperty
    onRowsInserted: console.log("rows were inserted")
    }

    ScrollView {
        anchors.fill: parent
        anchors.topMargin: buttons.implicitHeight + 10
        ListView {
            id: listView
            width: parent.width
            model: glav.list
            //required model
            delegate: Text {
                property var d
                d: model.modelData.id
                text: model.modelData.name
            }
            removeDisplaced: Transition {
                NumberAnimation { properties: "x,y"; duration: 100; easing.type: Easing.InOutQuad }
            }
}
}
}

dataobject.h

#ifndef DATAOBJECT_H
#define DATAOBJECT_H

#include <QObject>
namespace tile {
class DataObject : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QString name READ name WRITE setName NOTIFY changed)
    Q_PROPERTY(QString color READ color WRITE setColor NOTIFY changed)
    Q_PROPERTY(int id READ id WRITE setId NOTIFY changed)

public:
    explicit DataObject(QString name = "Wana", QString color = "red", int id = 1, QObject *parent = nullptr);

    QString name();
    void setName(const QString &name);

    QString color();
    void setColor(const QString &color);

    int id() const;
    void setId(int id);

signals:

    void changed();

private:

    QString m_name;
    QString m_color;
    int m_id;

};
}
#endif // DATAOBJECT_H

dataobject.cpp

#include "dataobject.h"

#include <QDebug>
namespace tile {
DataObject::DataObject(QString name, QString color, int id, QObject* parent) :
    QObject(parent)
    , m_name (name)
    , m_color (color)
    , m_id (id)
{
    //new DataObject();
    qDebug() << m_name;
    //emit changed();
}

QString DataObject::name()
{
    return m_name;
}

void DataObject::setName(const QString &name)
{
    m_name = name;
    qDebug() << m_name;
    emit changed();
}

QString DataObject::color()
{
    return m_color;
}

void DataObject::setColor(const QString &color)
{
    m_color = color;
    emit changed();
}

int DataObject::id() const
{
    return m_id;
}

void DataObject::setId(int id)
{
    m_id = id;
    emit changed();
}
}

glav.h

#ifndef GLAV_H
#define GLAV_H

#include <QObject>
#include <QLinkedList>

namespace tile {
class Glav : public QObject
{
    Q_OBJECT

    Q_PROPERTY( QLinkedList<QObject *> list READ list CONSTANT )
public:
    explicit Glav(QObject *parent = nullptr);

    //QLinkedList<QObject *> list();
    //void setList(const QLinkedList<QObject *> &list);

    Q_INVOKABLE QLinkedList<QObject *> pollist();
    Q_INVOKABLE void addItem();
//    Q_INVOKABLE QVariant pol();


signals:
    void changed();

private:
    QLinkedList<QObject *> m_list;
    QLinkedList<QObject *> list();

};
}
#endif // GLAV_H

glav.cpp

#include "glav.h"
#include "dataobject.h"

#include <QDebug>
#include <QAbstractListModel>

namespace tile {
Glav::Glav(QObject *parent) : QObject(parent)
{
    QLinkedList<QObject *> dataList = {
            new DataObject("Item 1", "red"),
            new DataObject("Item 2", "green"),
            new DataObject("Item 3", "blue"),
            new DataObject("Item 9", "yellow")
        };
    m_list << dataList;
    QVariant::fromValue(m_list);

}

QLinkedList<QObject *> Glav::list()
{
    return m_list;
}

//void Glav::setList(const QLinkedList<QObject *> &list)
//{
//    m_list = list;
//}


//QVariant Glav::pol(){

//     QVariant re = QVariant::fromValue(m_list);
//    return re;
//}


QLinkedList<QObject *> Glav::pollist()
{
    //qDebug() << QVariant::fromValue(m_list);
    //QLinkedList<QObject *> f = m_list;
    //QVariant::fromValue(m_list);
    //qDebug() <<m_list;
    return m_list;
}

void Glav::addItem()
{
    qDebug() << m_list.count();
    m_list << new DataObject();
    qDebug() << m_list.count();
    emit changed();
}
}

Upvotes: 2

Views: 141

Answers (1)

splaytreez
splaytreez

Reputation: 834

Your Glav class has a changed() signal but it doesn't do anything because your list property is constant (Q_PROPERTY( QLinkedList<QObject *> list READ list CONSTANT ))

You should change it to this:

Q_PROPERTY(QLinkedList<QObject*> list READ list NOTIFY changed)

That way you can let the ListView know that the list has just been changed by emitting the changed() signal.

Also, it's better to name the signal in accordance with the property it corresponds to: listChanged.

More info on how Q_PROPERTY works in the official documentation: https://doc.qt.io/qt-5/properties.html

Upvotes: 2

Related Questions