1

I am trying to make an editable model for a ListView in QML, using QAbstractListModel. Since it is stated in the Qt Documentation, I tried implementing setData() for my model, but I am facing several issues.

The setData() member function is defined as such:

bool setData(const QModelIndex &index, const QVariant &value, int role)

However, in my ListView delegate I have something like this:

MouseArea
        {
            anchors.fill: parent

            onClicked: elementClicked(index)
        }

Is there a proper way to cast the index to a QModelIndex to use it in setData()? I tried to craft a QModelIndex using this:

void MainWindow::onElementClicked(int index)
{
    AbstractItem x = mListModel.getItem(index); //Getting AbstractItem at specific index...
    x.setStatus(); //Changing a boolean value of AbstractItem

    QModelIndex idx = MIListModel.index(0, index, QModelIndex()); //using 0, since the ListView only has 1 row.

    qDebug() << index;
    MIListModel.setData(idx, x, Qt::EditRole); //...and then trying to pass it in setData() to replace the original one.
    qDebug() << "OK";
}

But then setData() always returns false. Using qDebug() << index.row() and qDebug() << index.column() inside setData(), I found out that the value for both row and column is -1, thus causing the failure.

Also, do I have to implement Qt::ItemFlags flags(const QModelIndex &index) const? In the Qt Documentation(it's the same link as above) they state that it is needed, but I found no relevant example of it being used for QML.

Finally, I am having trouble passing AbstractItem to setData(), since I am getting this:

cannot convert argument 2 from 'const QVariant' to 'const AbstractItem &'
with
[
    T=AbstractItem 
]

To resolve this, I tried using Q_DECLARE_METATYPE(AbstractItem), but I still get the same error. The only way I could temporarily solve this was changing the setData() member function to use a AbstractItem instead a QVariant. Is this even good practice?

To sum up my problem, I have these questions:

  • How can I cast an int to a QModelIndex to use in setData().
  • Do I also have to reimplement flags() to get an editable model. If so, how?
  • Is it a good idea to change the second argument of setData() to one of my choice? If not, how do I convert my class to QVariant?

If possible, I would also like a source where I can further study using QAbstractListModel with QML.

Edit: Removed additional question as it was off-topic.

SASUPERNOVA
  • 141
  • 1
  • 11
  • Documentation has this tutorial: http://doc.qt.io/qt-5/modelview.html It's a Qt Widgets example but the model concept still applies. – Tony Clifton Apr 28 '17 at 03:14
  • There is one point you err on: QML Models have **n rows, but only one column**. So the `QModelIndex` you need to create is: `MIListModel.index(index, 0)` rather than `MIListModel.index(0, index)` – derM - not here for BOT dreams Apr 28 '17 at 06:49
  • Unless you plan on dealing with very big models with millions of items, I'd recommend this implementation: http://stackoverflow.com/questions/35160909/how-to-create-a-generic-object-model-for-use-in-qml/35161903#35161903 It is extremely powerful and flexible, the model items can be completely arbitrary, you can have new item types without recompiling the C++ part, and you can populate models declaratively too. – dtech Apr 28 '17 at 07:18
  • After spending some hours studying and compiling, I found out some interesting things. First, I was indeed making a mistake with rows and columns. However, even when I change it, my ListModel doesn't update to reflect the changes in the underlying **MIListModel**. The Qt Widgets example provides some interesting information, but it doesn't help me with the ListView not being updated. As for the generic object model method, I found it pretty fascinating, but I don't understand how to use it for my own class. Do I replace **QList _data;** with my class, or do I do something else? – SASUPERNOVA Apr 28 '17 at 19:24
  • Nevermind, I figured generic object model out, but there is a question I would like to address. I edited my question. – SASUPERNOVA Apr 28 '17 at 20:32
  • You better post a new question if you have a new question. Keep to one question per "topic". Or if the questions are multiple, they should be closely related. And your new question is about something else entirely. – dtech Apr 28 '17 at 20:37
  • Thanks for your answer! I will do just that. – SASUPERNOVA Apr 28 '17 at 22:28

0 Answers0