Russian Qt Forum
Июнь 15, 2024, 21:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Окно загрузки данных  (Прочитано 16072 раз)
alexis031182
Гость
« Ответ #15 : Июнь 18, 2012, 20:07 »

...
Жаль что у вас не осталось исходников было бы интересно взлянуть на реализацию, думаю не только мне Улыбающийся.
Да не, раз говорят, что вьюха забирает с модели только нужные строки, значит смысл мой пример теряет. Может быть тогда это не было реализовано, а только спустя время. Я не помню, да и не суть. Значит Вам нужно лишь что-то подправить в модели, чтобы было тип-топ Улыбающийся
Записан
mutineer
Гость
« Ответ #16 : Июнь 18, 2012, 20:13 »

У меня вытекли глаза от этой простыни... Сегодня читать точно не буду, может завтра
Записан
vovan1982
Гость
« Ответ #17 : Июнь 18, 2012, 20:16 »

У меня вытекли глаза от этой простыни... Сегодня читать точно не буду, может завтра

Улыбающийся

Да не вопрос, буду рад совету, заранее прошу прощения за то что коментов в коде нет, это мой первый проект и пишу его сам, собственно процесс обучения и написания идёт параллельно.
Записан
Bepec
Гость
« Ответ #18 : Июнь 18, 2012, 20:23 »

Поток нужен. Обязательно. Собственно что можно посоветовать.
Простые варианты:
1) при перемещении ползунка отсчитывать позицию. Потом запрашивать лишь видимое число элементов. Т.е. максимум для 24 дюймового монитора - где то от 500 до 1,5к строк.
2) использовать Q*SqlModel. Насколько я помню, она прекрасно оптимизирована и у неё отсутствует описанный недостаток.
3) ну хз. Самый кривой способ - кешировать сразу все записи. В самом начале. Т.е. делаем окошко ожидания и загружаем сразу всё. Сколько-то там времени займёт, зато потом будет летать, если хватит оперативки Веселый

PS и маленький совет. Можно вместо окошка ожидания, выводить гифку загрузки аля Ютуб посередине Q*View. Гораздо понятнее пользователю и читать ненадо Веселый
Записан
vovan1982
Гость
« Ответ #19 : Июнь 18, 2012, 20:36 »

Поток нужен. Обязательно. Собственно что можно посоветовать.
Простые варианты:
1) при перемещении ползунка отсчитывать позицию. Потом запрашивать лишь видимое число элементов. Т.е. максимум для 24 дюймового монитора - где то от 500 до 1,5к строк.
2) использовать Q*SqlModel. Насколько я помню, она прекрасно оптимизирована и у неё отсутствует описанный недостаток.
3) ну хз. Самый кривой способ - кешировать сразу все записи. В самом начале. Т.е. делаем окошко ожидания и загружаем сразу всё. Сколько-то там времени займёт, зато потом будет летать, если хватит оперативки Веселый

PS и маленький совет. Можно вместо окошка ожидания, выводить гифку загрузки аля Ютуб посередине Q*View. Гораздо понятнее пользователю и читать ненадо Веселый

Спасибо Улыбающийся, буду учить потоки.
Записан
alexis031182
Гость
« Ответ #20 : Июнь 18, 2012, 20:48 »

Верес, Вы порвали в клочья последнюю надежду
Записан
Bepec
Гость
« Ответ #21 : Июнь 18, 2012, 20:50 »

Работа у меня такая. Там снайпер, тут эльф, здесь программист и разрушитель надежд, что всё так просто Веселый
Записан
Syveren
Гость
« Ответ #22 : Июнь 19, 2012, 10:35 »

А что если хранить только ключи в модели. А сам запрос на получение данных делать в методе QAbstractModel::data().
Я дулал так для списка - работало на ура.
Данный способ увеличил быстродействие загрузки с 2 минут, до 2 секунд
И ещё зависит от Субд подойдёт ли вам этот способ или нет.
Код
C++ (Qt)
// Первоночально при помощи запроса заполняем только idList данными первичного ключа.
//mutable QCache<const QString,CashData> cashList;
// cashData вызываеться при изменение положения вертикального скролл бара у QlistView.
void MyListModel::cashData(int from, int to)
{
   // Сохраняем в кеше информацию
   // from и to это номера строк в поле видимости
   // Загружаем информацию для строк с from по to
   // и сохраняем её в cashList;
   // (загрузка сразу нескольких значений из БД происходит быстрее, чем выгрузка их по отдельности)
   QStringList list;
   // Не имеет смысла запоминать больше максимального ограничения на cashList
   if(to - from > cashList.maxCost())
       to = from  + cashList.maxCost();
   for(int row = from; row <= to ;++row)
   {
       const QString* id  = & idList.at(row);
       if(!cashList.contains(*id))
           list<<"'" + *id + "'";
   }
   query.exec("SELECT id, ... , WHERE id IN (" + list.join(",") + ")") +   QString(" LIMIT %1 ").arg(to - from));
   while(query.next())
       cashList.insert(query.value(0).toString(),new CashData(query.value(1).toString(),query.value(2).toBool()));
}
 
QVariant MyListModel::data(const QModelIndex& index, int role) const
{
   switch(role)
   {
   case Qt::SizeHintRole:return size_hint;
   case Qt::DisplayRole:
   case Qt::ToolTipRole:
   {
       const QString* id  = & idList.at(row);
       if(id->isNull())
           return QVariant(tr("загрузка..."));
       if(cashList.contains(*id))//если в кеше уже есть текст для данной строчки выводим его
           return cashList.object(*id)->display_text;
       query.exec("...запрос... WHERE id ='" + *id + "' LIMIT 1");
       query.first();
       QString display_text = query.value(0).toString() + query.value(1).toString() +...;
       cashList.insert(*id,new CashData(display_text, query.value(1).toBool()));
       return  display_text;
   }
   case Qt::DecorationRole:
       return  QIcon(":icon");
   case  Qt::UserRole: return idList.at(row);
   default: return QVariant();
   }
}
 
« Последнее редактирование: Июнь 19, 2012, 21:07 от Syveren » Записан
alexis031182
Гость
« Ответ #23 : Июнь 19, 2012, 10:42 »

А что если хранить только ключи в модели. А сам запрос на получение данных делать в методе QAbstractModel::data().
Я дулал так для списка - работало на ура.
С одной стороны - хорошо, а с другой - будет множество мелких запросов к БД. Подход как у ORM.
Записан
Syveren
Гость
« Ответ #24 : Июнь 19, 2012, 10:59 »

 
Цитировать
С одной стороны - хорошо, а с другой - будет множество мелких запросов к БД. Подход как у ORM
Всё зависит от использоваемого драйвера SQL. Для драйвера QPSQL данный подход не принёс ничего ценного (он и без этих наворотов работал быстро). Но при использовании QODBC было колосальное ускорение.
Записан
Syveren
Гость
« Ответ #25 : Июнь 19, 2012, 11:03 »

Я и начал использовать данный подход, так как из-за смены СУБД, загрука стала вдруг такой медленной, что ни в какие ворота не лезло.
Записан
alexis031182
Гость
« Ответ #26 : Июнь 19, 2012, 11:21 »

Вот мне это всё непонятно. Сразу скажу, что с БД в Qt практически не занимался. Можно сказать, что опыт на нуле по этой теме. Работал всё больше в вебе, да и только с мускулом (MySQL).

По логике, если сравнить два подхода, то в первом:
А. парсинг мускулом запроса - O(1);
Б. возврат данных большим куском - O(n);

... а во втором появляется зависимость от кол-ва записей:
А. парсинг мускулом запроса - O(1);
Б. возврат данных маленьким куском - O(1).

При этом, второй подход выполняется n раз.

Дополнительно: в первом варианте можно использовать транзакцию, которая гарантирует существенное снижение длительности выполнения пункта Б.

Вопрос: что будет работать быстрее?
Записан
vovan1982
Гость
« Ответ #27 : Июнь 19, 2012, 13:11 »

А что если хранить только ключи в модели. А сам запрос на получение данных делать в методе QAbstractModel::data().
Я дулал так для списка - работало на ура.
Данный способ увеличил быстродействие загрузки с 2 минут, до 2 секунд
И ещё зависит от Субд подойдёт ли вам этот способ или нет.

Интересный вариант, надо будет попробовать.

Дополнительно: в первом варианте можно использовать транзакцию, которая гарантирует существенное снижение длительности выполнения пункта Б.

Вопрос: что будет работать быстрее?

Ни попробуешь не узнаешь Улыбающийся.

А на счёт транзакции можно подробней, я просто с ними не работал, каким образом транзакция уменьшает время запроса на выборку, я всегда думал что транзакция нужна для отката изменений и блокировки таблицы на время работы с ней.
Записан
alexis031182
Гость
« Ответ #28 : Июнь 19, 2012, 14:37 »

...
А на счёт транзакции можно подробней, я просто с ними не работал, каким образом транзакция уменьшает время запроса на выборку, я всегда думал что транзакция нужна для отката изменений и блокировки таблицы на время работы с ней.
За счёт одноразового обновления индексов у таблицы, одноразовых блокировки и предоставления доступа.
Записан
vovan1982
Гость
« Ответ #29 : Июнь 19, 2012, 15:17 »

А как mysql организовать транзакцию для выборки данных?
На сколько я знаю для обновления таблицы используется BEGIN; для начала транзакции и COMMIT; для внесения сделанных изменений или ROLLBACK для их отката.
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.08 секунд. Запросов: 20.