【问题标题】:setData returns false for QAbstractProxyModelsetData 为 QAbstractProxyModel 返回 false
【发布时间】:2017-05-17 08:58:18
【问题描述】:

我有 QAbstractProxyModel 的子类,它的源模型是 QSqlTableModel 的子类。代理模型一次只能显示一行源模型。代码如下:

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;
}

源模型:

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;
}

当必须将新行添加到源模型时调用以下命令:

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 是保存源模型当前行的私有成员。

setData() 总是返回 false。源模型设置为手动提交。我做错了什么?

编辑:

我发现了问题所在。我使用的源模型是QSqlTableModel 的子类,它为EditRole 以外的任何角色调用QSqlQueryModel 的setData。由于 QSqlQueryModel 本身并没有重新实现 setData,所以它调用 QAbstractItemModel 的 setData,它总是返回 false。

所以,我现在使用 EditRole 进行所有 setData() 调用,并且 data() 从存储在 EditRole 下的源模型返回值。

【问题讨论】:

  • 两个setData() 方法中的哪一个返回false? IE。代理的方法是自行返回 false 还是因为源模型的方法返回了?
  • 返回哪个false?您在代理模型中有三个“错误”。在主模型中有两个。
  • 主模型和代理模型的所有 setData 方法都返回 false。 sourceModel()->setData() 返回 false。
  • 行为不同..setData(createIndex(0, 0), QVariant(comboBoxItems), Qt::EditRole) 似乎返回true。
  • 在不覆盖 setData 的情况下尝试一下

标签: c++ qt qsqltablemodel


【解决方案1】:

您在此处仅为EditRoleDisplayRole 设置数据。其他角色,如ForegroundRole,不要设置,因为你返回false。显然您不需要对这两个模型进行子类化,因为您的代码除了标准类之外什么都不做。如果您想稍后添加一些代码,至少将第一个块中的最后一个 return false 更改为

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

最后一个 return false 在第二个块中

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

还有,这个:

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

没有任何意义。

【讨论】:

  • 我很抱歉..但我是使用 Qt 进行模型/视图编程的新手。我想为除第一列之外的所有编辑和显示角色设置相同的值。你能解释一下我做错了什么吗?
  • 您有与这两个角色相关的条件。无论如何,您都可以在此处设置数据,无论是第 0 列还是任何其他列。 if/else 块没有意义,因为在这两种情况下你都在做同样的工作。
  • 但是对于第一列中的任何一个角色,我传递的值都会不同。如果我要删除 else,两个角色的值不会设置为最后调用 setData() 的角色吗?
  • Qt 引擎的作用:它顺序检查角色的处理方式。例如,有EditRole。 Qt 调用 setData(...,...,Qt::EditRole) 并检查 whis 角色返回的内容。例如,下一个角色是DisplayRole。 Qt 调用setData(...,...,Qt::DisplayRole) 等等。如果没有提到子类中的某些角色,则应默认处理它们,即由我在回答中提到的父类的功能处理。
猜你喜欢
  • 1970-01-01
  • 2019-06-17
  • 1970-01-01
  • 2013-09-18
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多