updateRowInTable

Для понимания, когда вызывается функция 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.