Хочу изменить порядок обновления данных в QSqlTableModel |
Здравствуйте, гость ( Вход | Регистрация )
Хочу изменить порядок обновления данных в QSqlTableModel |
mva |
19.6.2009, 21:37
Сообщение
#1
|
Участник Группа: Участник Сообщений: 104 Регистрация: 15.3.2009 Из: Киров Пользователь №: 615 Спасибо сказали: 3 раз(а) Репутация: 0 |
Доброго времени суток всем!
Работаю с моделью QSqlTableModel/QTableView. EditStrategy == OnFieldChange. Все работает хорошо, но есть одно НО... Мне нужно, чтобы при изменении пользователем содержимого любой ячейки Grid эти изменения сразу же фиксировались на сервере без каких-либо задержек и нажатий дополнительных кнопок, просто при перемещении на другую ячейку. Класс QSqlTableModel при изменении данных в одной строке (ячейке) отсылает изменения на сервер (у меня PostgreSQL), а затем ЗАГРУЖАЕТ ТАБЛИЦУ ЦЕЛИКОМ. С большой таблицей в локальной сети это будет работать сносно, а через Интернет - думаю, что очень медленно. Поэтому хочу изменить порядок обновления данных в QSqlTableModel - так, чтобы изменения на сервер отсылались, а последующая загрузка таблицы не происходила... Зачем загружать все данные, если пользователь изменил лишь одну ячейку? Поясню на исходном коде класса QSqlTableModel.
Пытаюсь создать наследника класса QSqlTableModel и переопределить в нем функцию setData:
Проблема в том, что здесь используются какие-то недокументированные функции и переменные (например макрос Q_D и переменная d ), к которым я не знаю, как добраться. Код в таком виде не компилируется. А может быть есть более простой путь? |
|
|
MoPDoBoPoT |
20.6.2009, 0:28
Сообщение
#2
|
Участник Группа: Участник Сообщений: 172 Регистрация: 7.5.2009 Из: Москва Пользователь №: 738 Спасибо сказали: 44 раз(а) Репутация: 9 |
Проблема в том, что здесь используются какие-то недокументированные функции и переменные (например макрос Q_D и переменная d ) Эти вещи относятся к private-реализации класса (см. ичходники). Можешь конечно запихнуть Q_DECLARE_PRIVATE(SqlTableModel) в область private своей MySqlTableModel и тогда приватный класс становится доступным, НО это не панацея... Завтра поменяют реализацию приватной части и будешь локти кусать. |
|
|
Litkevich Yuriy |
20.6.2009, 2:03
Сообщение
#3
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
mva, как вариант, можно попробовать сделать средствами API.
Т.е. политику ставить "OnManualSubmit" ловить факт изменения данных, и собственно ручно их фиксировать в БД. Тогда, возможно, перечитывания данных из БД не будет. |
|
|
mva |
20.6.2009, 10:31
Сообщение
#4
|
Участник Группа: Участник Сообщений: 104 Регистрация: 15.3.2009 Из: Киров Пользователь №: 615 Спасибо сказали: 3 раз(а) Репутация: 0 |
mva, как вариант, можно попробовать сделать средствами API. Т.е. политику ставить "OnManualSubmit" ловить факт изменения данных, и собственно ручно их фиксировать в БД. Тогда, возможно, перечитывания данных из БД не будет. Установил политику в "OnManualSubmit". Исходя из документации в этом случае я должен использовать функцию QSqlTablemodel::submitAll(). Сделал, решил проверить сниффером какие данные идут на сервер и обратно. Получается, что при использовании фунции submitAll() на сервер ТРИЖДЫ отправляется один и тот же запрос на закачку данных и ТРИЖДЫ одинаковые данные передаются обратно. Этот вариант мне не подходит... |
|
|
mva |
24.6.2009, 11:02
Сообщение
#5
|
Участник Группа: Участник Сообщений: 104 Регистрация: 15.3.2009 Из: Киров Пользователь №: 615 Спасибо сказали: 3 раз(а) Репутация: 0 |
Решил я эту задачку... Пришлось изучать исходный код в части работы с базами данных. Как оказалось в этом плане Qt работает довольно примитивно. При использовании политики OnFieldChange результат изменений ячейки данных в Grid сначала отправляется на сервер, а затем для того, чтобы отобразить эти изменения, посылается запрос на загрузку всех данных... Это очень неэффективно... При использовании других политик происходит примерно то же самое, только с задержкой по времени. Для OnManualSubmit - изменения загружаются после команды submilAll. Но в этом случае изменения сохраняются в буфере и отображаются в виджете Grid. Этот момент я и использовал.
После множества экспериментов все свелось к простому дочернему классу:
При использовании этого класса вместо QSqlTableModel нет необходимости вызова submitAll для сохранении данных на сервере, хотя здесь и используется политика OnManualSubmit. Изменения сохраняются на сервере сразу, как только мы перемещаемся на другую ячейку, при этом фокус курсора не теряется (не изменяется). Это то, что мне и требовалось. Чем-то этот вариант похож на предложение Литкевича Юрия. |
|
|
SABROG |
24.6.2009, 12:21
Сообщение
#6
|
Профессионал Группа: Участник Сообщений: 1207 Регистрация: 8.12.2008 Из: Russia, Moscow Пользователь №: 446 Спасибо сказали: 229 раз(а) Репутация: 34 |
|
|
|
BRE |
24.6.2009, 13:11
Сообщение
#7
|
Профессионал Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: 44 |
В таблицах БД могут быть вычисляемые поля, данные в которых зависят от содержания других полей. Плюс к этому, если по содержимому этого поля идет сортировка, то порядок следования записи может измениться и должен быть изменени на экране, также интересные эффекты могут случиться при работе с фильтрами (изменили поле и оно перестало попадать под фильт в запросе, строка должна удалиться с экрана). |
|
|
Гость_Гость_mva_*_* |
24.6.2009, 14:01
Сообщение
#8
|
Гости |
В таблицах БД могут быть вычисляемые поля, данные в которых зависят от содержания других полей. Ничто не мешает использовать вычисляемые поля, если таковые имеются. Если эти поля входят в запрос - то вычислениями занимается сервер. Клиент всего лишь их отображает. А если они вычисляются в клиентском приложении, то в этом тоже нет никакой проблемы, т.к. этот дочерний класс сохраняет все свойства класса QSqlTableModel. Что касается фильтрации или сортировки, то никто не мешает вызывать функцию submitAll() для обновления отображения, как это предусмотрено использованием политики OnManualSubmit. Просто с использованием этого дочернего класса есть возможность сильно сократить трафик и ускорить работу приложения. |
|
|
Гость_asg128_* |
13.9.2011, 15:59
Сообщение
#9
|
Гости |
Можно также подключиться к сигналам CommitData (чтобы узнать, какая запись текущая) и CloseEditor (чтобы перейти к текущей записи после обновления QSqlTableModel) делегата (получается функцией itemDelegate модели). Потребуется чуть больше кода, зато корректно будет работать при наличии фильтров/сортировки.
|
|
|
Текстовая версия | Сейчас: 30.1.2025, 3:19 |