pra7
pra7

Reputation: 884

Creating a complex List Model in QML

I am using a ListView to display data. For that I use Component as a delegate and ListModel as the model to create rows in the ListView:

Below image is the use case for the design:

enter image description here

I use a function to create the model based on the data received from the C++. But since rows and columns are dynamic and also each small box as a checkbox to display I am not getting how to populate/create a model for this.

ListModel{
    id:myListModel
}

function createModel(){
    for(var rows = 0 ; rows < 10; rows++)
    {
        ListModel.append({}) //How to add data to model like a group based on the row and col ?
    }
}

As each small rectangle as checkboxes and columns are dynamic how to append data to the ListModel?

Please Suggest.

Upvotes: 0

Views: 1775

Answers (1)

JustWe
JustWe

Reputation: 4484

I created a QML list model on Github which is based on QAbstractListModel, you can refer it and create your own one.

I wrote a demo for your case, the Test class store the data which have two properties checkBox1 and checkBox2, and the TestModel is list container of Test.

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "QmlListModel.h"

class Test : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool checkBox1 MEMBER mCheckBox1)
    Q_PROPERTY(bool checkBox2 MEMBER mCheckBox2)
public:
    explicit Test(bool checkBox1 = false,
                  bool checkBox2 = false):
        mCheckBox1(checkBox1),
        mCheckBox2(checkBox2){}

    bool    mCheckBox1;
    bool    mCheckBox2;
};

class TestModel : public QmlListModel<Test>
{
    Q_OBJECT
    QML_LIST_MODEL
public:
    explicit TestModel(){}
};

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    // register the TestModel for QML.
    qmlRegisterType<TestModel>("QmlListModel", 1, 0 , "TestModel");

    TestModel* testModel = new TestModel;

    for(int i = 0; i < 9; ++i){
        testModel->appendData(new Test(false, false));
    }

    QQmlApplicationEngine engine;
    // put the data into QML context, make you can access it.
    engine.rootContext()->setContextProperty("testModel", testModel);
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    return app.exec();
}

#include "main.moc"

And how to use in QML:

import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Window 2.1

Window {
    visible: true
    width: test.width
    height: test.height

    Column {
        id: test
        spacing: 20
        Grid {
            columns: 3; rows: 3; spacing: 20
            Repeater {
                model: testModel
                delegate: Row {
                    CheckBox {
                        checked: checkBox1 // The property name
                        text: "checkBox1"
                        onCheckedChanged: testModel.get(index).checkBox1 = checked
                    }
                    CheckBox {
                        checked: checkBox2
                        text: "checkBox2"
                        onCheckedChanged: testModel.get(index).checkBox2 = checked
                    }
                }
            }
        }
        Button {
            text: "Debug"
            onClicked: {
                for(var i = 0; i < testModel.size(); i++){
                    console.log("index", i, "checkBox1 is", testModel.get(i).checkBox1);
                    console.log("index", i, "checkBox2 is", testModel.get(i).checkBox2);
                }
            }
        }
    }
}

Upvotes: 1

Related Questions