The dataChanged() signal should not be emitted until you submitAll() or revertAll() in the manual submit mode (or another view changes the data through the model) so I don't know how exactly you get the behaviour you describe. Are you using a table view or a QDataWidgetMapper? Single view or multiple?

QSqlTableModel::isDirty() can tell you if a given index is dirty or not. If you look for currentChanged() from the view's selection model then check the old index you might be part way there.