PDA

View Full Version : Populating sublassed QAbstractItemModel



been_1990
22nd December 2012, 14:41
When trying to insert items into my QAbstractItemModel:

ListModel * model = new ListModel();
for (int row = 0; row < 4; ++row) {
for (int column = 0; column < 4; ++column) {
model->insertRow(1);
qDebug() << model->setData(model->index(row),QVariant::QVariant("halooo"),Qt::EditRole);
qDebug() << model->data(model->index(row),Qt::EditRole);
}
}
Outputs:

false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)
false
QVariant(Invalid)

listmodel.h

#ifndef LISTMODEL_H
#define LISTMODEL_H

#include <QAbstractListModel>
#include <QStringList>

class ListModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit ListModel(QObject *parent = 0);
int rowCount( const QModelIndex & parent ) const;
QVariant data( const QModelIndex & index, int role /* = Qt::DisplayRole*/ ) const;
Qt::ItemFlags ListModel::flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index,const QVariant &value, int role);

private:
QStringList stringList;

signals:

public slots:

};

#endif // LISTMODEL_H

listmodel.cpp

#include "listmodel.h"
#include <QtDebug>

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

QVariant ListModel::data( const QModelIndex & index, int role /* = Qt::DisplayRole*/ ) const
{
// if an invalid row, return empty QVariant
if (index.row() < 0 || index.row() >= 4)
return QVariant();

switch( role )
{
case Qt::DisplayRole:
case Qt::EditRole:
{
QString s;
s = QString("row [%1]").arg( index.row() );
return QVariant(s);
}
default:
return QVariant();
}
}

bool ListModel::setData(const QModelIndex &index,
const QVariant &value, int role)
{
if (index.isValid() && role == Qt::EditRole) {

stringList.replace(index.row(), value.toString());
emit dataChanged(index, index);
return true;
}
return false;
}

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

return QAbstractItemModel::flags(index) /*|Qt::ItemIsEditable*/;
}

int ListModel::rowCount(const QModelIndex &parent) const
{
return stringList.count();
}


It seems like the index passed is never valid, "index.isValid()", so it never sets the data. What's wrong here?

anda_skoa
22nd December 2012, 17:31
You did not implement insertRows().
When your example code calls insertRow(), your string list stays at size 0 and so does rowCount().

If all you are storing is a list of strings and you are adding them from outside instead of having the model interfacing to already existing data, why not just use QStringListModel?

Cheers,
_

been_1990
22nd December 2012, 18:34
Yes, QStringListModel is what I should use. Do I have to create a custom class to set my model as not edotable?

wysota
22nd December 2012, 20:25
No, you don't.

been_1990
22nd December 2012, 21:25
The only way I know is to reimplement flags():

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

return QAbstractItemModel::flags(index) /*|Qt::ItemIsEditable*/;
}