C++子类化QSqlTableModel时setData返回true但无数据更新问题
问题原因及解决方案
以下是导致你修改不生效的核心问题及对应修复方案:
data函数父类调用错误
你子类继承的是QSqlTableModel,但data实现中调用的是QSqlQueryModel::data。QSqlQueryModel是只读模型,会缓存首次查询的数据集,不会读取QSqlTableModel修改后的缓存数据,所以你读取到的一直是初始值。
dataChanged信号参数错误
你当前发送信号用的是转换列后的内部索引、默认角色,外部通过自定义角色读取数据时,无法接收到对应变更通知,也会导致读取到旧值。
- (潜在问题)未重写
flags函数返回可编辑标志
如果没有重写flags函数返回Qt::ItemIsEditable,模型默认不支持编辑,也会导致修改不生效(你这里setData返回true说明可能已经处理了这个点,建议检查确认)
- (潜在问题)未重写
- (潜在问题)提交策略设置问题
如果QSqlTableModel设置了OnManualSubmit提交策略,需要手动调用submitAll()才会把修改同步到数据库,修改后内存缓存也会同步更新。
- (潜在问题)提交策略设置问题
修正后的核心代码
data函数修正
QVariant ItemModel::data(const QModelIndex & index, int role) const { // 自定义角色走字段映射逻辑 if (role >= Qt::UserRole + 1 && role <= WEIGHTROLE) { QModelIndex modelIndex = this->index(index.row(), role - Qt::UserRole); // 调用QSqlTableModel的data方法,读取最新修改的缓存数据 return QSqlTableModel::data(modelIndex, Qt::DisplayRole); } // 系统默认角色走父类逻辑 return QSqlTableModel::data(index, role); }
setData函数修正
bool ItemModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (role < Qt::UserRole + 1 || role > WEIGHTROLE) { // 非自定义角色走父类默认处理逻辑 return QSqlTableModel::setData(index, value, role); } QModelIndex modelIndex = this->index(index.row(), role - Qt::UserRole); bool setRes = QSqlTableModel::setData(modelIndex, value, Qt::EditRole); if (setRes) { // 发送正确的变更信号,携带修改的自定义角色 emit dataChanged(index, index, {role}); } qDebug() << "修改结果:" << setRes << "错误信息:" << lastError(); return setRes; }
可选:设置实时提交策略
如果需要修改字段后自动同步到数据库,初始化模型时设置提交策略:
// 字段修改后自动提交到数据库 itemModel->setEditStrategy(QSqlTableModel::OnFieldChange);
如果用手动提交策略,修改后需要调用submitAll():
itemModel->setData(index, "VALUE", itemModel->CONTENTROLE); itemModel->submitAll(); // 手动提交修改到数据库
内容的提问来源于stack exchange,提问作者dev-Bilal
相关产品推荐
相关产品推荐

