Для понимания, когда вызывается функция updateRowInTable:
1. При стратегии редактирования OnFieldChange в функции setData.
2. При стратегии редактирования OnRowChange только для режима вставки новой строки (insertIndex != -1) в функции submitAll.
3. При стратегии редактирования OnManualSubmit (только для строк кеша с признаком операции Update) в функции submitAll.
Итак главное, что надо понять: updateRowInTable вызывается только из функции setData(). Вставка и удаление строки это отдельный путь.
В первом случае (OnFieldChange) все предельно просто и submit|submitAll не надо вызывать никогда, так как updateRowInTable вызывается напрямую из setData.
Во втором случае (OnRowChange) после setData надо делать submit (который вызывет submitAll).
В третьем случае (OnManualSubmit) после setData надо вызывать submitAll, но только в том случае, когда все накопленные изменения надо скинуть в базу данных.
В случае успешного завершения updateRowInTable (запрос к базе проходит нормально) в всех трех случаях вызывается select запрос к базе данных и таблица обновляется.
Таким образом, чтобы быть уверенным, что изменения прошли нормально и таблица правильно обновилась в базе и на экране, нам надо только проверять возврат функции updateRowInTable на true. А это можно легко делать переопределив эту функцию в классе наследнике.
Вот как выглядит QSqlTableModel::updateRowInTable , тут просто выполняется запрос к базе данных:
bool QSqlTableModel::updateRowInTable(int row, const QSqlRecord &values)
{
Q_D(QSqlTableModel);
QSqlRecord rec(values);
emit beforeUpdate(row, rec);
const QSqlRecord whereValues = d->strategy == OnManualSubmit ? d->cache[row].primaryValues : d->primaryValues(row);
bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries);
QString stmt = d->db.driver()->sqlStatement(QSqlDriver::UpdateStatement, d->tableName,
rec, prepStatement);
QString where = d->db.driver()->sqlStatement(QSqlDriver::WhereStatement, d->tableName,
whereValues, prepStatement);
if (stmt.isEmpty() || where.isEmpty() || row < 0 || row >= rowCount()) {
d->error = QSqlError(QLatin1String("No Fields to update"), QString(),
QSqlError::StatementError);
return false;
}
stmt.append(QLatin1Char(' ')).append(where);
return d->exec(stmt, prepStatement, rec, whereValues);
}
Может показаться, что для обновления информации на экране (в таблице ) надо еще вызвать submit или submitAll, но это не так. Данные будут отображаться в соответствии с выбранной стратегией редактирования, где-то из кеша, где-то из editBuffer корректно.
Правда есть небольшой нюанс при стратегии OnRowChange.
Смотрите также еще: insertRowIntoTable и deleteRowFromTable.