c++qtlistviewqmlqabstractlistmodel

Empty ListView when integrating C++ Models in QT


Created C++ List Model to integrate with the QML to populate list view contains a check box and text view of 100 entries as given below

todomodel.cpp File

#include "todomodel.h"

ToDoModel::ToDoModel(QObject *parent)
    : QAbstractListModel(parent)
{
}

int ToDoModel::rowCount(const QModelIndex &parent) const
{
    if (!parent.isValid())
        return 0;

    // FIXME: Implement me!
    return 100;
}

QVariant ToDoModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    // FIXME: Implement me!
    switch(role) {
        case DoneRole:
            return QVariant(false);
        case DescriptionRole:
            return QVariant(QStringLiteral("Test"));
    }


    return QVariant();
}

bool ToDoModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (data(index, role) != value) {
        // FIXME: Implement me!
        emit dataChanged(index, index, QVector<int>() << role);
        return true;
    }
    return false;
}

Qt::ItemFlags ToDoModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::NoItemFlags;

    return Qt::ItemIsEditable; // FIXME: Implement me!
}

QHash<int, QByteArray> ToDoModel::roleNames() const
{
    QHash<int, QByteArray> names;
    names[DoneRole] = "done";
    names[DescriptionRole] = "description";
    return names;
}

todomodel.h file

#ifndef TODOMODEL_H
#define TODOMODEL_H

#include <QAbstractListModel>

class ToDoModel : public QAbstractListModel
{
    Q_OBJECT

public:
    explicit ToDoModel(QObject *parent = 0);

    enum {
        DoneRole = Qt::UserRole,
        DescriptionRole
    };

    // Basic functionality:
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

    // Editable:
    bool setData(const QModelIndex &index, const QVariant &value,
                 int role = Qt::EditRole) override;

    Qt::ItemFlags flags(const QModelIndex& index) const override;

    virtual QHash<int, QByteArray> roleNames() const override;
private:
};

#endif // TODOMODEL_H

ToDoList.qml File


import ToDo 1.0

Frame {
    ListView {
        //Listview needs model, a delegate,
        //the size determines the user interactive:
        implicitHeight: 250//same as wrap content in android
        implicitWidth: 250
        clip: true

        model: ToDoModel{}

        delegate: RowLayout{
            width: parent.width
            CheckBox {
                checked: model.done
                onClicked: model.done = checked
            }
            TextField {
                Layout.fillWidth: true
                text: model.description
                onEditingFinished: model.description = text
            }
        }
    }
}

main.cpp file

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>

#include "todomodel.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQuickStyle::setStyle("Material");

    qmlRegisterType<ToDoModel>("ToDo", 1, 0, "ToDoModel");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));

    return app.exec();
}

main.qml file

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

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

    ToDoList {
        anchors.centerIn: parent
    }
}

Result: Instead of showing 100 entries , It shows empty list as shown below. Kindly guide me where I am going wrong. enter image description here


Solution

  • You are specifying that your model has 0 zero rows when the parent is invalid (the root-level). You should change return 0; with return 100;:

    int ToDoModel::rowCount(const QModelIndex &parent) const
    {
        if (parent.isValid()) //changed here
            return 0;
    
        // FIXME: Implement me!
        return 100;
    }