Russian Qt Forum
Ноябрь 23, 2024, 11:59
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Базы данных
>
QSqlQueryModel и нормальный refresh
Страниц: [
1
]
2
3
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: QSqlQueryModel и нормальный refresh (Прочитано 18602 раз)
xokc
Птица говорун
Offline
Сообщений: 976
QSqlQueryModel и нормальный refresh
«
:
Сентябрь 22, 2014, 20:47 »
Как сделать нормальный, "обычный" refresh QTableVeiw, прицепленного к QSqlQueryModel?
Что имею ввиду под "нормальным":
1. собственно обновление изменившихся данных (новые/удаленные/изменившиеся строки) - это собственно сделано;
2. восстановление текущей позиции в QTableView - сделано, если текущая строка присутствует в обновленной модели;
3. если текущая строка в обновленной модели отсутствует - позиционироваться на следующую, если следующих нет тоже, то - на предыдущую.
Например, были такие строки:
1
2
3
4
5 - эта текущая
6
7
После обновления остались строки:
1
3
6 - эта должна стать текущей
7
Пока ничего лучшего придумать не могу кроме как, до обновления сохранять ключи для всех строки модели, перечитывать её, и потом в обновленной искать нужный индекс. Но, как-то этот из пушки по воробьям. Кто-нибудь предложит что-нибудь более совершенное?
Записан
Bepec
Гость
Re: QSqlQueryModel и нормальный refresh
«
Ответ #1 :
Сентябрь 23, 2014, 07:51 »
Запоминать номер строки? Если у вас нет удаления нескольких записей, то вполне можно по номеру строки ориентироваться.
Записан
xokc
Птица говорун
Offline
Сообщений: 976
Re: QSqlQueryModel и нормальный refresh
«
Ответ #2 :
Сентябрь 23, 2014, 19:26 »
С чего вы взяли, что нет удаления нескольких записей? Это самая обычная многопользовательская БД - пользователи творят, что хотят и добавляют сколько им вздумается и удаляют, соответственно. Так что вариант с номерам строки не проходит однозначно. Как-то же оно реализовано в том же delphi, например. Там никогда вообще не задумывался над этим - всё идеально работало "из коробки" на даже самой банальной связке из DataSource и Grid, не говоря уже о продвинутых комбинациях типа FIBPlus + DevExpress. Тут же, даже чтобы банально обновить изменившееся в БД значение приходится весь query переустанавливать. Лучше бы вместо своих qml свистоперделок нормальный DB MVC сделали, а не этот костыль. Накипело, блин.
Записан
Figaro
Гость
Re: QSqlQueryModel и нормальный refresh
«
Ответ #3 :
Сентябрь 23, 2014, 19:54 »
Первичный ключ запоминайте...
Записан
xokc
Птица говорун
Offline
Сообщений: 976
Re: QSqlQueryModel и нормальный refresh
«
Ответ #4 :
Сентябрь 23, 2014, 22:49 »
И что мне с этого ключа? Вы пример мой смотрели? Что делать если запись с этим ключом удалили?
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: QSqlQueryModel и нормальный refresh
«
Ответ #5 :
Сентябрь 24, 2014, 07:18 »
Цитата: xokc от Сентябрь 23, 2014, 19:26
Так что вариант с номерам строки не проходит однозначно.
Не понял почему. Если номера удаляемых/вставляемых строк известны - что мешает пересчитать номер после выполнения операции ?
Записан
xokc
Птица говорун
Offline
Сообщений: 976
Re: QSqlQueryModel и нормальный refresh
«
Ответ #6 :
Сентябрь 24, 2014, 08:04 »
Цитата: Igors от Сентябрь 24, 2014, 07:18
Если номера удаляемых/вставляемых строк известны - что мешает пересчитать номер после выполнения операции ?
Дак откуда мне они известны? Да и что такое "номер строки"? Приложения работают на разных компах, пользователи сортируют таблицы как угодно. Строка номер 2 у одного пользователя может означать что угодно у другого!
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: QSqlQueryModel и нормальный refresh
«
Ответ #7 :
Сентябрь 24, 2014, 08:17 »
Цитата: xokc от Сентябрь 24, 2014, 08:04
угодно. Строка номер 2 у одного пользователя может означать что угодно у другого!
Нужно уметь определять номер записи по уникальному id и id по номеру записи.
Перед рефрешем - определяете по номеру выбранной строки id записи, делаете рефрш, а после - находите по этому id номер строки.
Записан
xokc
Птица говорун
Offline
Сообщений: 976
Re: QSqlQueryModel и нормальный refresh
«
Ответ #8 :
Сентябрь 24, 2014, 08:31 »
Ну опять - посмотрите пример из первого поста. Перед рефреш у меня id текущей записи = 5, текущий № строки = 5. После рефреша получаю набор записей, в котором нет id=5 (кстати как именно мне это определить? на клиенте делать model->match() или на сервере в рамках транзакции исполнять ХП, которая перебирает записи в поиске номера строки?). И вот когда нет у меня после рефреш записи с запомненным id = 5 как мне встать на ту строку, которую я ожидаю увидеть (а именно № 4)?
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: QSqlQueryModel и нормальный refresh
«
Ответ #9 :
Сентябрь 24, 2014, 10:53 »
Цитата: xokc от Сентябрь 24, 2014, 08:31
Ну опять - посмотрите пример из первого поста.
А для таких манипуляций, вам придется хранить табличку соответствий row - id до рефреша.
До:
1 - 62
2 - 63
3 - 91
4 - 43
5 - 12 - текущая
6 - 23
7 - 24
После:
1 - 62
2 - 91
3 - 23
4 - 24
Мы знаем, что до рефреша текущей была строка с id = 12, пытаемся найти такую запись в выборке после, такой записи нет.
Лезем в таблицу "До" и смотрим id следующей записи id = 23 - пытаемся найти ее в результирующей выборке - нашли, это row = 3.
Записан
OKTA
Гость
Re: QSqlQueryModel и нормальный refresh
«
Ответ #10 :
Сентябрь 24, 2014, 11:05 »
Что-то я понять не могу, в чем проблема сделать запрос, который будет искать запись с нужным id, а если такой записи нет, то брать следующую по возрастанию или предыдущую при отсутствии записей с большим id??
Записан
xokc
Птица говорун
Offline
Сообщений: 976
Re: QSqlQueryModel и нормальный refresh
«
Ответ #11 :
Сентябрь 24, 2014, 13:25 »
Цитата: Old от Сентябрь 24, 2014, 10:53
Мы знаем, что до рефреша текущей была строка с id = 12, пытаемся найти такую запись в выборке после, такой записи нет.
Лезем в таблицу "До" и смотрим id следующей записи id = 23 - пытаемся найти ее в результирующей выборке - нашли, это row = 3.
Цитата: OKTA от Сентябрь 24, 2014, 11:05
В чем проблема сделать запрос, который будет искать запись с нужным id, а если такой записи нет, то брать следующую по возрастанию или предыдущую при отсутствии записей с большим id??
Этот-то вариант понятен его я и имел ввиду когда говорил в первом посте про "до обновления сохранять ключи для всех строки модели, перечитывать её, и потом в обновленной искать нужный индекс".
Но при этом мне нужно:
1. Хранить результат выборки до обновления с учетом всех манипуляций, которые умудрился над запросом совершит пользователь (сортировки и фильтрации на клиенте). Допустим это QList<int> oldKeys с ключами записей.
2. После обновления проверять в ней наличие (и снова - как проверять: через model->match()?) ключа текущей записи. Если её там нет - крутить цикл по oldKeys вниз от текущей строки до обнаружения в новой модели очередного ключа. Если такой не найдется, то делать тоже самое вверх по oldKeys. Если опять ничего не найдется - то позиционироваться на первой записи.
Но это же трындец! А если у меня запрос возвращает не 20, а 2000 записей? Это же банальный
обычный
refresh!!! Кто-то (что-то) это же делает в других фреймворках! Почему в Qt это всё должен делать я сам? Требую метод refresh на уровне QTableView!!!
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: QSqlQueryModel и нормальный refresh
«
Ответ #12 :
Сентябрь 24, 2014, 13:39 »
Цитата: xokc от Сентябрь 24, 2014, 13:25
А если у меня запрос возвращает не 20, а 2000 записей?
Список из 2000 64-битных id это 128Кб памяти.
Цитата: xokc от Сентябрь 24, 2014, 13:25
Кто-то (что-то) это же делает в других фреймворках!
Да как-то так и делают, только спрятано это под капотом.
Цитата: xokc от Сентябрь 24, 2014, 13:25
Почему в Qt это всё должен делать я сам? Требую метод refresh на уровне QTableView!!!
Можно требовать или сделать один раз свою модель для работы с БД.
«
Последнее редактирование: Сентябрь 24, 2014, 13:43 от Old
»
Записан
xokc
Птица говорун
Offline
Сообщений: 976
Re: QSqlQueryModel и нормальный refresh
«
Ответ #13 :
Сентябрь 24, 2014, 17:08 »
Цитата: Old от Сентябрь 24, 2014, 13:39
Список из 2000 64-битных id это 128Кб памяти.
Дело то не в объемах памяти. А в том, что мне придется обновленную модель прогонять (кстати, так и никто и не предложил как это делать "правильно") достаточно большое количество раз на предмет поиска в ней "наиболее меня устраивающего" (в смысле "ближайшего") к искомому id. А если в модели присутствуют блобы? Боюсь тогда fetch для всех её записей в рамках исполнения model->match() может "несколько затянуться". Ну а если этих записей вдруг станет 20000?
Цитата: xokc от Сентябрь 24, 2014, 13:25
Можно требовать или сделать один раз свою модель для работы с БД.
Можно и сделать. Но так можно и до собственной ОС докатиться. Хочется решать прикладные задачи, а не реализовывать такие свои модели, тем более что была надежда на то, что кто-то это сделает за (и лучше) меня.
«
Последнее редактирование: Сентябрь 24, 2014, 21:56 от xokc
»
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: QSqlQueryModel и нормальный refresh
«
Ответ #14 :
Сентябрь 25, 2014, 10:30 »
Цитата: xokc от Сентябрь 24, 2014, 13:25
Допустим это QList<int> oldKeys с ключами записей.
Напрашивается аналогичный newKeys считываемый после обновления, а дальше сравнение 2 массивов. И лучше напр QMap. После восстановления selection oldLКeys замещается на newKeys. Если модель обновляется извне - ничего лучшего не видно. В общем случае нет "ID записи", поэтому рассчитывать на сервис не приходится.
Цитата: xokc от Сентябрь 24, 2014, 13:25
Но это же трындец! А если у меня запрос возвращает не 20, а 2000 записей? Это же банальный
обычный
refresh!!! Кто-то (что-то) это же делает в других фреймворках! Почему в Qt это всё должен делать я сам? Требую метод refresh на уровне QTableView!!!
Вот это и есть обратная сторона Qt
Что-то сделать руками - уже западло. В конце-концов остаются "ручки", и это плохо. Считайте что Вы получили "заряд бодрости"
Записан
Страниц: [
1
]
2
3
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...