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

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

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

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

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

фотка 1

QTableView

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

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

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

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

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

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

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

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

Если стратегия модели onRowChanged то можно устанавливать всем полям значения через setData, они помещаются в editBuffer, submit будет вызываться автоматом в коде исходников Qt, но только при начале  редактировании уже другой строки .

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

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

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

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

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

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