Привет коллеги.
Перечитал все доступные мне источник Qt-информации, но так пока и не могу понять, как оформить нижеследующий сценарий работы приложения.
Приложение работает с информацией хранящейся на SQL-сервере.
Эпизод работы приложения:
1. ТАБЛИЧНАЯ ФОРМА отображает результат сложного SELECT-а из нескольких таблиц SQL-сервера.
Изменять ТАБЛИЧНУЮ ФОРМУ прямо с экрана запрещено. (есть кнопки - "Изменить" "Добавить" )
2. При их нажатии отрывается специальная ФОРМА для коррекции/добавления записи.
После закрытия этой ФОРМЫ выполняется серия UPDATE/INSERT-выражений меняющих таблицы на SQL-сервере.
3. Есть на ТАБЛИЧНОЙ ФОРМЕ кнопка "Удалить".
Её нажатие влечёт за собой серию DELETE/UPDATE-выражений также меняющих таблицы на SQL-сервере.
4. После проведённого изменения/добавления/удаления на SQL-сервере ТАБЛИЧНАЯ ФОРМА должна отразить новое состояние данных.
ВНИМАНИЕ ! Изменяли/добавляли/удаляли всего ОДНУ логическую запись сложного SELECT-а !
Как перечитав ТОЛЬКО её ОДНУ из базы отобразить её новое состояние в ТАБЛИЧНОЙ ФОРМЕ ?
Если произошло добавление как добавить ТОЛЬКО новую строку в ТАБЛИЧНУЮ ФОРМУ ?
Ну и естественно при удалении как удалить соответствующую строку из ТАБЛИЧНОЙ ФОРМЫ не перечитывая весь сложный SELECT заново ?
В приложении описанный эпизод повторяется МНОГОкратно , потому хочется его сделать оптимальным.
Связка QSqlTableModel+QTableView не подходит, т.к. порождает неоправданно частые селекты к таблицам.
Да и таб.формы опираются на сложные селекты , а не на таблицы.
О существовании VIEW и STORED PROCEDURE как альтернативы знаю, только куда частые перезапросы денешь?
Сделал submitAll() и тем самым родил перезапрос.
Связка QSqlQueryModel+QTableView объявлена как READ-ONLY.
Говорят - реализуй flags(), setData() и будет тебе EDIT-ABLE.
Только не говорят как сделать (INSERT/DELET)-ABLE.
И что теперь делать ?
Неужели "руками" из QSqlQuery заполнять QTableWidget и уже в нём ins/edit/del организовывать?
Приложение, о котором пишу, содержит около 70 табличных форм и к ним столько же форм редактирования строк.
Да плюс 100 репортов.
В базе более 100 таблиц. Есть среди них со 100 тыс. записей и всё это будет утолщятся.
Представляете себе реакцию приложения на исправление одной опечатки в одном слове одного поля одной табличной формы со 100 тыс записей
при перезапросах всего селекта ! Правим одну букву, а перечитываем ....
Ну жалко ведь барышень-операторов заполняющих ежедневно базу новыми документами.
А как быть - пока не знаю.
Java-Swing-Postgresql аналог вышеупомянутого приложения уже дорос до верcсии 3.034.
Теперь вот обратно хочу переехать(перевести приложение) на родной С++ (с него когда то ушёл в яву).
masterlan, QSqlTableModel+QTableView не так уж и плох если сабкласить модель с мануал сабмит.
Эх, была ни была! Вот, держи мою модельку:
Table_Model::Table_Model(QObject *parent) :
QSqlTableModel(parent)
{
setEditStrategy(QSqlTableModel::OnManualSubmit);
}
Qt::ItemFlags Table_Model::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = QSqlQueryModel::flags(index);
if (index.column()) flags |= Qt::ItemIsEditable;
return flags;
}
bool Table_Model::setData(const QModelIndex &index, const QVariant &value, int role)
{
bool lResult = QSqlTableModel::setData(index, value, role);
if (lResult) {
QSqlRecord rec = record(index.row());
if (value.toString().isEmpty()) rec.setNull(index.column());
else rec.setValue(index.column(), value);
rec.setGenerated(index.column(), true);
lResult = updateRowInTable(index.row(), rec);
}
return lResult;
}
QVariant Table_Model::headerData(int section, Qt::Orientation orientation, int role) const
{
if (section < 0 || role != Qt::DisplayRole) return QVariant();
if (orientation == Qt::Vertical) return index(section, 0).data();
return QSqlTableModel::headerData(section, orientation, role);
}
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)