0

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.

pra7
  • 834
  • 2
  • 21
  • 50
  • It sounds like you need something more like a table view than a list view. – dtech Feb 25 '18 at 01:26
  • @dtech There is no `TableView` in QT QUICK 2 !!! – pra7 Feb 25 '18 at 01:32
  • 1
    You could use a 2d model. However `ListModel` doesn't support model nesting. You can use this guy right here https://stackoverflow.com/questions/35160909/how-to-create-a-generic-object-model-for-use-in-qml – dtech Feb 25 '18 at 01:36
  • 1
    Or maybe use a grid view... – dtech Feb 25 '18 at 01:37
  • @dtech thanks for the link and i have never used `AbstractItemModel` for populating data and will try that. It would have been great if QML has a nested model. – pra7 Feb 25 '18 at 01:44
  • You could maintain the model entirely on the C++ side, and the model can only be an adapter to the actual data rather than duplicating it. – dtech Feb 25 '18 at 02:08

1 Answers1

1

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);
                }
            }
        }
    }
}
JustWe
  • 4,250
  • 3
  • 39
  • 90