Как контроллировать ввод данных в таблицу

Тут речь будет о том как контролировать ввод данных в таблицу данных , реализованных на QTableView и QSqlTableModel.

Есть такое предположение, что наиболее правильным подходом будет переопределение класса QSqlTableModel и класса QTableView.

Попытка связать сигнал dataChanged у QTableView или аналогичный у QSqlTableModel будет ошибочной идеей , так как в dataChanged приходит событие, когда уже ничего не изменить.

Тоже можно сказать и о beforeUpdate, в котором в общем-то уже контроллировать нечего и данные записываются в базу.

фотка 1

QTableView

Мы исходим из того , что все действия иницируются руками пользователя, то есть интерактивно, в нашем случае из QTableView.

Есть три варианта действий с таблицей : создание новой строки таблицы (или копирование строки) , удаление строки и редактирование строки, а именно конкретного поля строки.

Копирование строки

Надо сразу отмести функцию insertRecord по той причине, что на вход ей передается QSqlRecord, у которого могут быть Relation поля, то есть внешние связи к другим таблицам.

Так вот в этом поле будет текстовая замена из внешней таблицы , а нам надо получать id поля. И это будет тупиковая ситуация.

Далее остается функция insertRow() и это правильное начало , так как она только инициирует начало создания новой строки.

Далее происходит первый вызов setData для какого-нибудь поля .

Если стратегия модели в данный момент onFieldChange, то тут же происходит скрытый submit и возникает updateRow.

Если стратегия модели onRowChanged или onManualSubmit, то можно устанавливать всем полям значения через setData, они помещаются в кэш и в конце надо вызывать submit или submitAll.

Когда используют разные стратегии модели данных.

submit и submitAll производят запись в базу данных через QSqlQueryModel, это ранний родитель у QSqlTableModel.

Надо понимать, что все в результате идет через обычные sql запросы.

И после submitAll возникает insertRowIntoTable, где уже пошел запрос insert row к базе и контроллировать значения уже поздно.

Таким образом контроль должен реализовываться в setData. В setData проверяем значение поля на валидность и возвращаем либо true, либо false.

Также в зависимости от значения поля A тут же в setData можно вызвать setData поля B. И это нормально работает.