Russian Qt Forum

Qt => Базы данных => Тема начата: mwChief от Март 12, 2010, 08:24



Название: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: mwChief от Март 12, 2010, 08:24
Таблица из базы грузится в QSqlTableModel, для отображения данных на форме использую QDataWidgetMapper, вывожу все в несколько виджетов doubleSpinBox и lineEdit и один tableView (при выборе элемента в tableView doubleSpinBox`ы и lineEdit`ы заполняются соотвествующими значениями). Политика обновления у модели OnManualSubmit, сохраняю по нажатию кнопки. Нужно выдать предупреждение о несохраненных данных если пользователь внесет изменения и попытается закрыть окно не сохранив их.
Как лучше это отслеживать? Поиск в Assistante привел к QAbstractItemModel::isDirty() и  QAbstractItemModel::dataChanged(). isDirty вроде бы то что нужно, но проверяет только один элемент а не всю модель. Как пользоватся dataChanged() не совсем понял, не уверен что может подойти.
Форма выглядит вот так:
(http://lh6.ggpht.com/_bFkLbDSEg-g/S5nPXvjKqeI/AAAAAAAAA88/cjyCaD-lB1Y/s400/form.jpg)



Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: BRE от Март 12, 2010, 08:53
Как пользоватся dataChanged() не совсем понял, не уверен что может подойти.
Соединяешь этот сигнал со своим слотом, в котором переменной modified присваивается true.
При закрытии окна, проверяешь эту переменную и если она true, выводишь предупреждение.

Или пробегаешься по всем индексам модели и делаешь проверку isDirty...

Жаль, что Тролли не предусмотрели специальный метод, сообщающий есть ли данный в кеше изменений. Кода там на несколько строк.


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: mwChief от Март 12, 2010, 08:57
А он не сработает если поставить курсор к примеру в lineEdit, но ничего не изменив снова перенести курсор в другое место? Если сработает, то как лучше всего обрабатывать подобные ситуации?


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: BRE от Март 12, 2010, 09:00
А он не сработает если поставить курсор к примеру в lineEdit, но ничего не изменив снова перенести курсор в другое место? Если сработает, то как лучше всего обрабатывать подобные ситуации?
Он сработает, если для модели будет вызван setData, а такое возможно только если в одном из полей пользователь что-то изменит.


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: Павел_F. от Март 12, 2010, 09:09
Как пользоватся dataChanged() не совсем понял, не уверен что может подойти.
Соединяешь этот сигнал со своим слотом, в котором переменной modified присваивается true.
При закрытии окна, проверяешь эту переменную и если она true, выводишь предупреждение.
Может быть ситуация когда пользователь поменяет значение, потом второй раз поменяет на предыдущее. Фактически изменений нет, а переменная в true. Тут что-то хитрее нужно.


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: BRE от Март 12, 2010, 09:11
Может быть ситуация когда пользователь поменяет значение, потом второй раз поменяет на предыдущее. Фактически изменений нет, а переменная в true. Тут что-то хитрее нужно.
А QSqlTableModel тоже не отслеживает такие изменения, т.е. в кеше будет отмечено обновить это поле, и это будет выполнено при submitAll().


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: mwChief от Март 12, 2010, 09:29
Что то нехочет ловится QAbstractItemModel::dataChanged(). Пробую так:
void on_model_dataChanged ( const QModelIndex & topLeft, const QModelIndex & bottomRight );

model - имя модели

дальше как бы я ни менял данные на форме, в эту функцию я не попадаю.


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: BRE от Март 12, 2010, 09:34
Попробуй подключить сигнал используя connect.  :)


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: mwChief от Март 12, 2010, 09:46
Через connect заработало, но сигнал срабатывает даже когда я не менял данные, а просто поставил курсор.


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: BRE от Март 12, 2010, 09:57
Через connect заработало, но сигнал срабатывает даже когда я не менял данные, а просто поставил курсор.
А в QDataWidgetMapper какая политика обновления установлена?

Цитировать
QDataWidgetMapper::AutoSubmit   0   Whenever a widget loses focus, the widget's current value is set to the item model.


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: mwChief от Март 12, 2010, 10:27
Если поменять политику сохранения, я только отложу во времени запись в модель. По вызову submit мапппер также пишет в модель "новые" значения даже если я только прошел по ним курсором.
Может стоит копать в сторону модели? Унаследоваться от QSqlTableModel и сделать свою модель с блекджеком и со своим setData который будет проверять действительно ли отличается новое значение от уже имеющегося, и будет в зависимости от этого менять какой-то флаг?


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: mwChief от Март 13, 2010, 13:56
Мыслю правильно? :)


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: lit-uriy от Март 13, 2010, 14:06
>>Мыслю правильно?
ну как вариант, в общем-то


Название: Re: Как узнать были ли внесены изменения в QSqlTableModel
Отправлено: mwChief от Март 13, 2010, 18:43
А какие еще есть варианты?