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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Перехват update  (Прочитано 18265 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Март 23, 2018, 15:56 »

Добрый день

Есть большая таблица с массой ф-ционала. Многие действия юзера вызывают вставку/удаление строк из таблицы. Суетиться на каждое - тормоза, поэтому кеширую изменения и посылаю событие. Там в обработчике все меняю "скопом" и вызываю update окна. Вроде все путем, но иногда каким-то образом прорывается update и начинается отрисовка строк данные которых уже удалены. Ладно, в paintEvent проверяю пуст ли кеш изменений, и если нет - выхожу из paint'а вон.  Это неаккуратно, иногда видно "подмигивание", да и лишняя перерисовка "не украшает" при хорошем размере данных. Как сделать чисто?

Доп инфа. Таблица - наследник QWidget, не имеет никакого отношения к QTableWidget и.т.п. Рассматривал QWidget::setUpdatesEnabled, но не вижу как его здесь заюзать. Было бы здОрово поставить breakpoint на update но как это сделать именно для данной таблицы?

Спасибо
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Март 24, 2018, 15:44 »

Было бы здОрово поставить breakpoint на update но как это сделать именно для данной таблицы?
Без толку, т.к. отрисовка всё-равно асинхронная.
Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Март 26, 2018, 09:55 »

Попробовал проигнорировать QEvent::UpdateRequest (т.е. если окно не валидно - рисование пропускаем). НЕ работает. Попробовал setUpdatesEnabled - (при первом заполнении кеша false, когда сбросил кеш - true). Тоже НЕ работает. Как-то мне с этим setUpdatesEnabled все время не везет, пока ни разу не удалось его приспособить.

В обоих случаях окно остается замороженным, и оживает после возюкания мыши (может при смене курсора, хз). Ставлю тестовый qDebug(), печатается как положено и все работает как и было задумано. Мда, хреновато...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Апрель 01, 2018, 12:25 »

Отловил ситуацию когда окно НЕ перерисовывается после setUpdatesEnabled(true) - когда окно теряет фокус, напр бубочка (вызывающая setUpdatesEnabled) нажимается из др окна. Тогда UpdateRequest не посылается, судя по исходникам, окно уже "dirty".

Ладно, нашел такой workaround: делаю setUpdatesEnabled не для окна, а для его виджета, т.е. большой таблицы. Это срабатывает всегда, но.. после этого следующий вызов window->update() (т.е для окна) уже не перерисовывает таблицу  Плачущий  Приходится и там апдейтить таблицу (а не окно)

Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #4 : Апрель 06, 2018, 21:32 »

Уапрос, насколько частые вставки? Мы в свое время решали похожую задачу на айтемвьюхах, там были ОЧЕНЬ частые обновления и ОЧЕНЬ много данных.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Апрель 07, 2018, 12:09 »

Уапрос, насколько частые вставки? Мы в свое время решали похожую задачу на айтемвьюхах, там были ОЧЕНЬ частые обновления и ОЧЕНЬ много данных.
Ну "тысячи" - дело рядовое (напр объекты читаются из файла). Хотя в прынцыпе - какая разница, главное > 1
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #6 : Апрель 07, 2018, 19:34 »

"Тысячи" чего? rps какой? Тысячи в час и в секунду - разная вещь.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Апрель 08, 2018, 05:48 »

"Тысячи" чего? rps какой? Тысячи в час и в секунду - разная вещь.
Чего = вставок (Вы же о них спрашивали). За какое время - хз, ну пока все объекты не будут считаны с диска.

Кстати, такая ситуация: посылается сигнал с QueuedConnection, до этого возможно были update(), но в событийный цикл не выходили. Вопрос: гарантируется ли что слоты сигнала сработают ДО рисования?
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #8 : Апрель 09, 2018, 14:46 »

А зачем вы уведомляете вью на каждую вставку? Реализуйте механизм аналогичный BeginResetModel/EndResetModel - на EndResetModel просто перечитывать видимое состояние модели и перерисовать всё один раз.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Апрель 10, 2018, 06:57 »

А зачем вы уведомляете вью на каждую вставку? Реализуйте механизм аналогичный BeginResetModel/EndResetModel - на EndResetModel просто перечитывать видимое состояние модели и перерисовать всё один раз.
Не видел этого механизма, да и моменты Begin/End известны далеко не во всех случаях. Я кручу такой сюжетик

- окно получает запрос на вставку (удаление, изменение, и.т.п.). Запрос запоминается, перерисовка блокируется и, если это первый запомненный запрос, посылается сигнал "обновить данные" с QueuedConnection

- рано или поздно будет выход в событийный цикл и получим сигнал обновления. Пересобираем таблицу и разблокируем перерисовку.

Да, какие-то update могут просочиться как до первого запроса, так и после - но отловить их нереально. Вроде как классический случай блокировки рисования - но штатное средство не работает как положено  Плачущий
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #10 : Апрель 10, 2018, 17:06 »

Я не очень понимаю, причем тут кьювед коннекшн.
Пришли данные большой пачкой (файл) - положили их в модель, уведомили вью о том, что надо всё перерисовать.
Пришли данные маленькой пачкой (из формочки или днд) - уведомили вью что надо обновить кусочек.

Как я понимаю, сейчас уведомление идет на каждый чанк (строку) данных из файла - это и надо поправить сперва.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Апрель 11, 2018, 09:44 »

Я не очень понимаю, причем тут кьювед коннекшн.
Пришли данные большой пачкой (файл) - положили их в модель, уведомили вью о том, что надо всё перерисовать.
Пришли данные маленькой пачкой (из формочки или днд) - уведомили вью что надо обновить кусочек.

Как я понимаю, сейчас уведомление идет на каждый чанк (строку) данных из файла - это и надо поправить сперва.
Нету там никакого model-view (в терминах Qt). Что впрочем ничего не меняет. Фактически модель - вектор, на каждый чих дергать - уже плохо. Пачек тоже нету - приходят по одному, просто напр при чтении файла их может оказаться много (до выхода в событийный цикл). Поэтому "уведомление" лучше организовать самому, вот и QueuedConnection
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #12 : Апрель 11, 2018, 13:25 »

Ну вот советую сделать модель-вид. Всё же, их не в Qt придумали:)
Если вы посмотрите на QTextEdit - это тот же model-view (и даже контроллер там есть внутре).
Дергать вектор на каждый чих легко и приятно:) Если объемы данных ну очень большие, то можно заюзать std::deque, у ей внутре чанки, а значит вставка в середину быстрее, чем у вектора.
Но опять же, ничто не мешает вставить в конец вектора и отсортировать.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Апрель 11, 2018, 14:30 »

Дергать вектор на каждый чих легко и приятно:) Если объемы данных ну очень большие, то можно заюзать std::deque, у ей внутре чанки, а значит вставка в середину быстрее, чем у вектора.
Но опять же, ничто не мешает вставить в конец вектора и отсортировать.
Ну такие соображения не принципиальны, кеширование - прием фундаментальный, и тратить время чтобы как-то обойтись без него не стоит. Текущее решение совершенно нормально, вот почему штатная блокировка рисования глючит - вот вопрос.

Ну вот советую сделать модель-вид. Всё же, их не в Qt придумали:)
Никогда не верил в этот магический модель-вид  Улыбающийся Куча людей повторяет что-то типа "модель хранит, вьюха отображает!" (какой пассаж), но по-моему реально за этим ничего не стоит. Ну хорошо, вот допустим было бы у меня "по всем канонам", model-view (опись, протокол, отпечатки пальцев) и.. что с того?
положили их в модель, уведомили вью
Это не годится ни так ни сяк.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #14 : Апрель 11, 2018, 14:48 »

Никогда не верил в этот магический модель-вид  Улыбающийся Куча людей повторяет что-то типа "модель хранит, вьюха отображает!" (какой пассаж), но по-моему реально за этим ничего не стоит. Ну хорошо, вот допустим было бы у меня "по всем канонам", model-view (опись, протокол, отпечатки пальцев) и.. что с того?

Вам не пришлось бы мутить с отложенными событиями, которые куда-то там "прорываются".
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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