setData returns false for QAbstractProxyModel

1k views Asked by At

I have subclassed QAbstractProxyModel and its source model is a subclass of QSqlTableModel. The proxy model must show just one row of the source model at a time. Here's the code:

bool SensorDisplayModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(!index.isValid())
        return false;

    QModelIndex sourceIdx = mapToSource(index);

    if(role == Qt::DisplayRole || role == Qt::EditRole)
    {
        if(sourceIdx.isValid())
        {
            if(sourceModel()->setData(sourceIdx, value, role))
            {
//                emit dataChanged(index, index);
                return true;
            }
            return false;
        }
        else
            return false;
    }

    return false;
}

Source Model:

bool SensorModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(!index.isValid())
        return false;

    if(role == Qt::EditRole || role == Qt::DisplayRole)
    {
        if(index.column() != 0)
            return QSqlTableModel::setData(index, value, Qt::EditRole)  &&
                QSqlTableModel::setData(index, value, Qt::DisplayRole);
        else
            return QSqlTableModel::setData(index, value, role);
    }

    return false;
}

The following is called when a new row has to be added to the source model:

void SensorDisplayModel::addSensor()
{
    QString ro_id;
    bool success = false;

    if(sensorModel->insertRows(sensorModel->rowCount(), 1))
    {
        selectedRow = sensorModel->rowCount() - 1;
        ro_id = "DB-" + QString("%1").arg(SensorDisplayModel::id_no,
                                          3, 10, QChar('0'));
        comboBoxItems.append(ro_id);
        success = setData(createIndex(0, 0), QVariant(comboBoxItems), Qt::EditRole);
        success &= setData(createIndex(0, 0), QVariant(ro_id), Qt::DisplayRole);
        SensorDisplayModel::id_no++;
        success &= setData(createIndex(0, 1), QVariant(QString("Name")));
        success &= setData(createIndex(0, 2), QVariant(-1));
        success &= setData(createIndex(0, 3), QVariant(-1));
        success &= setData(createIndex(0, 4), QVariant((long long)0));
        success &= setData(createIndex(0, 5), QVariant(QString("??")));
        success &= setData(createIndex(0, 6), QVariant(QString("??")));

        if(success)
            emit dataChanged(createIndex(0, 0), createIndex(0, columnCount() - 1));

        ID2Row[data(createIndex(0, 0)).toString()] = selectedRow;
    }
}

selectedRow is a private member that saves the current row of the source model.

The setData() always returns false. The source model is set to manual submit. What am I doing wrong?

Edit:

I figured out the problem. The source model I use is a subclass of QSqlTableModel, which calls QSqlQueryModel's setData for any role other than EditRole. Since QSqlQueryModel in itself does not reimplement setData, it call QAbstractItemModel's setData which always returns false.

So, I now make all setData() calls with EditRole and data() returns values from the source model stored under EditRole.

1

There are 1 answers

4
AudioBubble On

Here you set data only for EditRole and DisplayRole. Other roles, such as ForegroundRole, don't set because you return false. Apparently you don't need to subclass both models, because your code does nothing other than the standard classes do. If you want to add some code later, at least change your last return false in first block to

return QAbstractProxyModel::setData(index,value,role);

and last return false in second block to

return QSqlTableModel::setData(index,value,role);

Also, this:

    if(index.column() != 0)
        return QSqlTableModel::setData(index, value, Qt::EditRole)  &&
            QSqlTableModel::setData(index, value, Qt::DisplayRole);
    else
        return QSqlTableModel::setData(index, value, role);

doesn't have any sense.