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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Анимация в делегате  (Прочитано 15563 раз)
vregess
Гость
« Ответ #15 : Июль 24, 2012, 22:35 »

Не особенно бредовая, в условиях необходимости, имхо. По сути да не меняет.
Представь что это модель состояний каких-нибудь датчиков, где в одной из колонок меняется параметр, есть сигнал-нет сигнала. Состояние меняется часто.
А делегат рисует данные двух колонок в одной Шокированный В итоге видим анимацию.
Смотря на заголовок топика я представляю себе таблицу, где в некоторых ячейках нарисована звезда, которая изредка бликует.

Цитата: andrew.k
Ты не можешь пинать делегатов, ты можешь пинать только вьюху, а вьюха пинает делегатов. Это раз.
Это и имелось ввиду.

Цитата: andrew.k
Обновить ты можешь только ячейку, а если код отрисовки громоздкий, то это потеря производительности. Это два.

Похоже это связано с
Цитата: andrew.k
Теперь фокус. Т.к. в моей модели не используется колонка в индексе, то можно использовать ее для передачи флага от модели к делегату. По этому флагу делегат может определить нужна ли отрисовка целиком ячейки, либо только анимированной части.
Это даст выигрыш в производительности в случае если метод paint сильно нагружен и если сразу много анимированных ячеек.

Что мешает в нем закешировать тяжелую графику...
И зачем использовать " колонку в индексе", если есть роли - передавай там флаг.

Цитата: andrew.k
Если готов обсуждать этот вопрос, прочти тему по последней ссылке, а то повторяем то, что и так ясно. И если будет, что добавить милости просим.

Да, я перечитал топик. И остался при своем мнении.
Как бы я сделал:
1) Делаем свой View на базе нужного:
* запускаем таймер и ловим таймаут в onAnimationTimeout()
* добавляем метод регистрации элементов модели (используя индекс), где нужна анимация

Код:
// Псевдокод
void MyView::onAnimationTimeout()
{
    foreach (registered index)
    {
        if (index is visible)
        {
           delegate = itemDelegate(index);
           delegate->setDrawAnimation(true);
           update(index);
        }
    }
}

2) Делаем базовый делегат для анимации с методами setDrawAnimation(bool)/isDrawAnimation().
В методе paint() что-нибудь подобное:

Код:
  if (isDrawAnimation())
    // обновляем анимацию и сбрасываем флаг анимации
  else
    // рисуем, используя данные из модели
Записан
andrew.k
Гость
« Ответ #16 : Июль 25, 2012, 11:31 »

Не особенно бредовая, в условиях необходимости, имхо. По сути да не меняет.
Представь что это модель состояний каких-нибудь датчиков, где в одной из колонок меняется параметр, есть сигнал-нет сигнала. Состояние меняется часто.
А делегат рисует данные двух колонок в одной Шокированный В итоге видим анимацию.
Смотря на заголовок топика я представляю себе таблицу, где в некоторых ячейках нарисована звезда, которая изредка бликует.
Ну, например, так.

Цитата: andrew.k
Обновить ты можешь только ячейку, а если код отрисовки громоздкий, то это потеря производительности. Это два.

Похоже это связано с
Цитата: andrew.k
Теперь фокус. Т.к. в моей модели не используется колонка в индексе, то можно использовать ее для передачи флага от модели к делегату. По этому флагу делегат может определить нужна ли отрисовка целиком ячейки, либо только анимированной части.
Это даст выигрыш в производительности в случае если метод paint сильно нагружен и если сразу много анимированных ячеек.

Что мешает в нем закешировать тяжелую графику...
Не все можно закешировать.
И кстати тоже отдельный вопрос, как бы ты реализовывал кеширование в делегате?

И зачем использовать " колонку в индексе", если есть роли - передавай там флаг.
Затем, чтобы делегат различал два события. Обновление айтема или обновление только кадра анимации. Через роли этого не добиться.

Цитата: andrew.k
Если готов обсуждать этот вопрос, прочти тему по последней ссылке, а то повторяем то, что и так ясно. И если будет, что добавить милости просим.

Да, я перечитал топик. И остался при своем мнении.
Как бы я сделал:
1) Делаем свой View на базе нужного:
* запускаем таймер и ловим таймаут в onAnimationTimeout()
* добавляем метод регистрации элементов модели (используя индекс), где нужна анимация

2) Делаем базовый делегат для анимации с методами setDrawAnimation(bool)/isDrawAnimation().

Это будет работать с глюками. Не понял, когда ты планируешь переключать делегат в обычный режим.
В тот момент когда ты переключишь делегат в режим рисования анимации, может потребоваться полная отрисовка айтема, а у тебя делегат в режиме анимации. И привет.
Записан
vregess
Гость
« Ответ #17 : Июль 25, 2012, 14:27 »

Цитата: andrew.k
И кстати тоже отдельный вопрос, как бы ты реализовывал кеширование в делегате?
Что-нибудь такое: QMap<QModelIndex,QPixmap>

Цитата: andrew.k
Затем, чтобы делегат различал два события. Обновление айтема или обновление только кадра анимации. Через роли этого не добиться.
Не совсем ясно, почему не добиться.

Цитата: andrew.k
Не понял, когда ты планируешь переключать делегат в обычный режим.

Цитировать
if (isDrawAnimation())
    // обновляем анимацию и сбрасываем флаг анимации

Хотя это можно сделать в методе onAnimationTimeout()
Код:
// Псевдокод
void MyView::onAnimationTimeout()
{
    foreach (registered index)
    {
        if (index is visible)
        {
           delegate = itemDelegate(index);
           delegate->setDrawAnimation(true);
           update(index);
           delegate->setDrawAnimation(false); // вот тут
        }
    }
}

Цитата: andrew.k
В тот момент когда ты переключишь делегат в режим рисования анимации, может потребоваться полная отрисовка айтема, а у тебя делегат в режиме анимации. И привет.

Тут я не совсем уверен, как работает update() у View (есть ли там какие-нибудь оптимизации по количеству вызовов), но по идее все это будет происходить последовательно. И даже если надо будет отрисовать анимацию и обновление модели, то произойдет это последовательно, тк выполняется в одном потоке в одном цикле сообщений.
Записан
andrew.k
Гость
« Ответ #18 : Июль 25, 2012, 16:16 »

Цитата: andrew.k
И кстати тоже отдельный вопрос, как бы ты реализовывал кеширование в делегате?
Что-нибудь такое: QMap<QModelIndex,QPixmap>
Ок.

Цитата: andrew.k
Затем, чтобы делегат различал два события. Обновление айтема или обновление только кадра анимации. Через роли этого не добиться.

Не совсем ясно, почему не добиться.
Потом что делегат не сможет определить, кто инициировал событие отрисовки.
Ты предлагаешь переключать флаг в модели, но в этот момент кто-то подвинул окно или развернул и делегат собрался рисовать, а у тебя в модели флаг анимации.
А передавая флаг в индексе, делегат всегда будет точно знать что нужно рисовать, т.к. индекс, который передаст вьюха будет без колонки (c == 0)

Цитата: andrew.k
Не понял, когда ты планируешь переключать делегат в обычный режим.
Теперь понял.

Тут я не совсем уверен, как работает update() у View (есть ли там какие-нибудь оптимизации по количеству вызовов), но по идее все это будет происходить последовательно. И даже если надо будет отрисовать анимацию и обновление модели, то произойдет это последовательно, тк выполняется в одном потоке в одном цикле сообщений.
Есть. Update не выполняет мгновенной перерисовки, а лишь добавляет событие в очередь.
И теоретически может так случиться, что оно придет позже или раньше, чем ты ожидаешь.
Записан
vregess
Гость
« Ответ #19 : Июль 25, 2012, 16:24 »

Цитировать
Есть. Update не выполняет мгновенной перерисовки, а лишь добавляет событие в очередь.
И теоретически может так случиться, что оно придет позже или раньше, чем ты ожидаешь.

void QAbstractItemView::update ( const QModelIndex & index ) != void QWidget::update ()
Записан
andrew.k
Гость
« Ответ #20 : Июль 25, 2012, 17:07 »

Цитировать
Есть. Update не выполняет мгновенной перерисовки, а лишь добавляет событие в очередь.
И теоретически может так случиться, что оно придет позже или раньше, чем ты ожидаешь.

void QAbstractItemView::update ( const QModelIndex & index ) != void QWidget::update ()
Согласен, но думаю работают они одинаково.
Записан
vregess
Гость
« Ответ #21 : Июль 25, 2012, 18:30 »

Согласен, но думаю работают они одинаково.

Посмотрел исходники - да, внутри вызывается QWidget::update().
Ну тогда надо заменить на repaint():

Код:
// Псевдокод
void MyView::onAnimationTimeout()
{
    foreach (registered index)
    {
        if (index is visible)
        {
           delegate = itemDelegate(index);
           delegate->setDrawAnimation(true);
           const QRect& rect = visualRect(index);
           repaint(index);
        }
    }
}
Записан
andrew.k
Гость
« Ответ #22 : Июль 25, 2012, 18:34 »

Согласен, но думаю работают они одинаково.

Посмотрел исходники - да, внутри вызывается QWidget::update().
Ну тогда надо заменить на repaint():

Код:
// Псевдокод

           repaint(index);
        }
    }
}
Нет такого метода и даже если был, это не круто было бы.
Записан
andrew.k
Гость
« Ответ #23 : Июль 25, 2012, 18:37 »

На данный момент я отказался от этой идеи, но потом в научных целях попробую реализовать.

Пока можно просто пообсуждать)
« Последнее редактирование: Июль 25, 2012, 18:44 от andrew.k » Записан
vregess
Гость
« Ответ #24 : Июль 25, 2012, 19:45 »

Нет такого метода и даже если был, это не круто было бы.

ошибся, надо repaint(rect);
Записан
andrew.k
Гость
« Ответ #25 : Июль 25, 2012, 19:49 »

Нет такого метода и даже если был, это не круто было бы.

ошибся, надо repaint(rect);
не круто  Подмигивающий
Записан
andrew.k
Гость
« Ответ #26 : Июль 26, 2012, 11:10 »

Цитата: andrew.k
И кстати тоже отдельный вопрос, как бы ты реализовывал кеширование в делегате?
Что-нибудь такое: QMap<QModelIndex,QPixmap>
Со временем такой кеш будет разрастаться.
Например, модель была вообще очищена, а кеш продолжает хранить.
Как очищать его от неиспользуемых элементов?
Записан
vregess
Гость
« Ответ #27 : Июль 27, 2012, 11:02 »

Можно ловить сигнал удаления элементов в делегате, но боюсь для тебя это не слишком крутое решение.
Записан
Bepec
Гость
« Ответ #28 : Июль 27, 2012, 14:16 »

Вы б лучше сделали Веселый А там уже критики найдутся Веселый

PS я тоже хочу анимированные гифки в model-view!
Записан
andrew.k
Гость
« Ответ #29 : Июль 27, 2012, 14:34 »

Вы б лучше сделали Веселый А там уже критики найдутся Веселый

PS я тоже хочу анимированные гифки в model-view!
Так вперед:
Цитировать
Ну тогда тебе такой ответ - наиболее красиво будет со своей отрисовкой.

Наиболее незатратно - QPropertyAnimation.

Или ты только советовать можешь?
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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