как работает setData

Посмотрим QSqlTableModel::setData(..).


bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    Q_D(QSqlTableModel);
    if (role != Qt::EditRole)
        return QSqlQueryModel::setData(index, value, role);

    if (!index.isValid() || index.column() >= d->rec.count() || index.row() >= rowCount())
        return false;

    bool isOk = true;
    switch (d->strategy) {
    case OnFieldChange: {
        if (index.row() == d->insertIndex) {
            QSqlTableModelPrivate::setGeneratedValue(d->editBuffer, index.column(), value);
            return true;
        }
        d->clearEditBuffer();
        QSqlTableModelPrivate::setGeneratedValue(d->editBuffer, index.column(), value);
        isOk = updateRowInTable(index.row(), d->editBuffer);
        if (isOk)
            select();
        emit dataChanged(index, index);
        break; }
    case OnRowChange:
        if (index.row() == d->insertIndex) {
            QSqlTableModelPrivate::setGeneratedValue(d->editBuffer, index.column(), value);
            return true;
        }
        if (d->editIndex != index.row()) {
            if (d->editIndex != -1)
                submit();
            d->clearEditBuffer();
        }
        QSqlTableModelPrivate::setGeneratedValue(d->editBuffer, index.column(), value);
        d->editIndex = index.row();
        emit dataChanged(index, index);
        break;
    case OnManualSubmit: {
        QSqlTableModelPrivate::ModifiedRow &row = d->cache[index.row()];
        if (row.op == QSqlTableModelPrivate::None) {
            row.op = QSqlTableModelPrivate::Update;
            row.rec = d->rec;
            QSqlTableModelPrivate::clearGenerated(row.rec);
            row.primaryValues = d->primaryValues(indexInQuery(index).row());
        }
        QSqlTableModelPrivate::setGeneratedValue(row.rec, index.column(), value);
        emit dataChanged(index, index);
        break; }
    }
    return isOk;
}


Итак setData пишет в кэш модели данных, submit записывает в базу данных чере QSqlQuery запросы. submitAll

Может показаться , что можно записывать данные от роли отличной от EditRole. Но изначально это не так роли в модели данных.

Логгируем работу модели данных QSqlRelationalTableModel и ее представления QTableView.

setData вызывается например интерактивным элементом управления в QTableView при установке нового значения в поле.

Например делает ComboBoxDelegate в setModelData индекс [1x6] newValue : 0. То есть тут и вызывается setData модели данных с целью установить новое значение.

В модели данных выпускается сигнал dataChanged (конкретно в QSqlTableModel) , который можно связать со своим слотом, чтобы проверять устанавливаемое значение на валидность. Но на самом деле проверять что-то уже поздно.

То есть обрабатывая dataChanged можно как сделать submit, так и revert установки нового значения, но только не для стратегии OnFieldChange.


ComboBoxDelegate::createEditor [1x6] parent objName qt_scrollarea_viewport option  " QStyleOption( SO_ViewItem , LeftToRight , QStyle::State( "Active | Enabled | HasFocus" ) , QRect(439,30 90x29) ) 
"ComboBoxDelegate::updateEditorGeometry [1x6] option "   option :  QStyleOption( SO_ViewItem , LeftToRight , QStyle::State( "Active | Enabled | HasFocus" ) , QRect(439,30 90x29) ) 
ComboBoxDelegate::slot_currentIndexChanged commitData currentIndex() :  -1 
ComboBoxDelegate::slot_currentIndexChanged commitData currentIndex() :  0 
"ComboBoxDelegate::setModelData [1x6]  newValue : 0" 
   ComboBoxDelegate::setModelData model->setData(index, newValue, Qt::EditRole) 
my_TableView_Purchases::dataChanged return 
testCheck::purch_dataChanged 
     "taxCode"  :  "0" 
testCheck::slot_beforeUpdatePurch  field :  "taxCode"   isGenerated :  true  newVal  QVariant(int, 0) 
table_QSqlRelationalTableModel::updateRowInTable row  1   true 

testCheck::purch_dataChanged submitAll  true 
 ComboBoxDelegate::setModelData model->setData(index, newValue, Qt::EditRole) :  true 
table_QSqlRelationalTableModel::updateRowInTable row  -1   false 
 ComboBoxDelegate::setModelData model->submit()  false   newValue  0

Примечание: setData и submit для установки нового значения использует в итоге те же sql команды типа UPDATE ...