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

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

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: Помогите организовать мигание иконки внутри делегата  (Прочитано 32828 раз)
neosapient
Гость
« : Февраль 02, 2010, 13:30 »

Здравствуйте.

Есть собственная модель, которая отображается в TableView. Вместе они образуют таблицу, в которой надо прикрутить столбец alarm.

То есть при наступлении определенного момента, в столбец alarm начинает мигать иконка. И мигает она до тех пор, пока на неё не кликнут.

Предполагаю, что придеться писать свой собственный делегат, который позволит организовать мигание.
Вижу несколько задач:
1) Определиться с тем, как должна выглядеть модель с данными.
2) Определиться с тем, как информировать компоненты программы о старте мигания.
3) Разработать делегат, который будет самостоятельно управлять миганием
4) Так же делегат должен реагировать на команду старта мигания и отлавливать клик мыши, для стопа  мигания.


Как я вижу пункты 1 и 2: в мою модель я могу добавить ещё один столбец. По умолчанию, в слотбце будет находиться значение 0. Как только произойдет alarm-событие, то в этой ячейке 0 смениться на 1. Далее делегат, при значении 1 должен начать мигание, а значение ячейки перевести в состояние 2. В тот же момент должен быть запущен "таймер", который задаст такт мигания.
Вот тут для меня начинается путаница. Либо таймер должен поднимать/сбрасывать какой то флаг, а делегат всего лишь отображает иконку в одном из состояний флага. Либо "таймер" должен посылать сигналы делегату с указанием, что тот должен отображать. Либо мигание следует положить на плечи самого делегата и изменять модель с данными лучше не следует....

Прошу вашего совета, о том как правильно организовать мигание иконки в ячейке столбца? Возможно есть готорые примеры с миганием в ячейках таблицы.

Записан
Павел_F.
Гость
« Ответ #1 : Февраль 02, 2010, 19:22 »

В столбце отобразить иконку( возвращать в зависимости от значения нужный пиксмап через data по Qt::DecorationRole). В модели сделать таймер и по нему в setData менять значение. И без делегата иконка будет меняться, стоит лишь запустить таймер.
« Последнее редактирование: Февраль 02, 2010, 19:26 от Павел_F. » Записан
neosapient
Гость
« Ответ #2 : Февраль 03, 2010, 18:39 »

Цитировать
В столбце отобразить иконку( возвращать в зависимости от значения нужный пиксмап через data по Qt::DecorationRole). В модели сделать таймер и по нему в setData менять значение. И без делегата иконка будет меняться, стоит лишь запустить таймер.

Практически так и сделал.
Запустил QTimeLine в режиме "меандра". В моделе создал массив флагов. В QAbstractTableModel::data() проверяю отдаваемые значения. Если оно является "опасным", то в массиве устанавливается соответствующий флаг. Настроил QTimeLine  отсылать сигнал dataChanged() два раза в секунду. Когда TableView запрашивает значение в мигающем столбце,  QAbstractTableModel::data()  возвращает картинку при сочетании трех условий: 1) сейчас "опасное" значение 2) никто не кликал по мигающей ячейке 3) сейчас такт QTimeLine, при котором следует показать иконку.
Оно работает...

Но в моем представлении, модель не должна управлять "анимацией" в делегате. Поэтому хочу понять, как правильно разделить модель и анимацию. В идеале я должен подставлять 0 или 1, а делегат должен осуществлять анимацию, а так же отсылать к QTableView сигнал о необходимости обновить подопечную ячеку.
Записан
crossly
Гость
« Ответ #3 : Февраль 03, 2010, 20:44 »

вообще не логично что бы модель управляла миганием... по идее в модели должно быть 2 состояния ... есть аларм или его нету... по этому сувай таймер в делегат...
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #4 : Февраль 03, 2010, 21:41 »

2 crossly,
+1
Записан

Юра.
neosapient
Гость
« Ответ #5 : Февраль 05, 2010, 13:55 »

Цитировать
вообще не логично что бы модель управляла миганием... по идее в модели должно быть 2 состояния ... есть аларм или его нету... по этому сувай таймер в делегат...
Только тут встает другая проблема - как мне сказать TableView, что таймер требует обновить делегат в такой то ячейке? 
Ведь надо, чтобы делегат знал индекс ячейки для обновления, чтобы он потом от лица модели послал сигнал в слот TableView::update ( const QModelIndex & index ). Делать очень грамоздкую обвеску не хочется... Есть пример с элегантным решением ?
Записан
crossly
Гость
« Ответ #6 : Февраль 07, 2010, 21:19 »

а зачем тебе говорить об этом tableview .... таймер у тебя будет в делегате... делегат в ячейке... вот и все...
Записан
Kolobok
Гость
« Ответ #7 : Февраль 07, 2010, 22:06 »

вообще не логично что бы модель управляла миганием... по идее в модели должно быть 2 состояния ... есть аларм или его нету... по этому сувай таймер в делегат...
Еще более нелогично делать таймер в делегате. Я даже больше скажу, это невозможно без очень большой
черезжопности, а может и вообще невозможно. Можно мигание организовать во view, но это довольно сложно.
В модели же это всего несколько строчек.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Февраль 07, 2010, 22:37 »

Не вдаваясь в конкретные подробности реализации:

1) Расслабиться. Задачка простая - значит и решаться должна просто

2) Таймер завязать на таблицу (а не на ячейку) - это однозначно. А вдруг кто-то еще захочет мигать?

3) Таблица получает сигнал от таймера и передает его выбранной ячейке (может строке/столбцу) - а та уж знает что с ним делать (по умолчанию - ничего), простой virtual, хорошо подходит множественное наследование
Записан
Kolobok
Гость
« Ответ #9 : Февраль 08, 2010, 13:05 »

Задачка простая - значит и решаться должна просто
Если что-то дешево, значит это плохо? Бывает, простые задачи вообще не имеют решения. Ни простого, ни сложного.

2) Таймер завязать на таблицу (а не на ячейку) - это однозначно. А вдруг кто-то еще захочет мигать?
Так этот вариант вообще еще не обсуждался. Было предложено хранить таймер в модели, вью или делегате. Кстати, это очень неплохой вариант.
В мигающие ячейки сажать виджет и коннектить его с таймером. Подходит для небольших таблиц.

3) Таблица получает сигнал от таймера и передает его выбранной ячейке (может строке/столбцу) - а та уж знает что с ним делать (по умолчанию - ничего), простой virtual, хорошо подходит множественное наследование
Честно говоря, не понимаю что здесь написано.
Что значит выбранная ячейка? Откуда вью знает, какие ячейки должны мигать?
Что значит передать ячейке? Ячейка - это QModelIndex.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #10 : Февраль 08, 2010, 13:50 »

>>Ячейка - это QModelIndex.
Нет. Ячейка в пердставлении - это делегат.
QModelIndex - это координата и только.
Записан

Юра.
Kolobok
Гость
« Ответ #11 : Февраль 08, 2010, 15:22 »

>>Ячейка - это QModelIndex.
Нет. Ячейка в пердставлении - это делегат.
QModelIndex - это координата и только.
Неинтуитивное название делегата. Таблица с одной ячейкой звучит более чем странно.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Февраль 08, 2010, 15:35 »

Что значит выбранная ячейка? Откуда вью знает, какие ячейки должны мигать?
Что значит передать ячейке? Ячейка - это QModelIndex.
Data model всегда есть. Нарастите этот класс чтобы он умел давать разные цвета ячейкам, напр.

Код:
class MyDataModel : public QAbstractItemModel {
....
virtual void data( ..);  // добавить выдачу для Qt::BackgroundRole
...

void NextBlink( void ) { mBlinkState = (mBlinkState + 1) % 2; }

QVector <QModelIndex> mBlinkCell; // массив мигающих ячеек
int mBlinkState:                          // напр. 0 = синий, 1 = красный и.т.п.
};
По таймеру таблица говорит модели NextBlink и вызывает перерисовку нужных ячеек.
Правда, судя по исходникам, background (возвращаемый data) будет игнорироваться для выделенных ячеек если showDecorationSelected = true в стиле. Но оно public, так что можно напр. перекрыть paint для делегата. Короче, раскрасить ячейку можно  Улыбающийся
Записан
Kolobok
Гость
« Ответ #13 : Февраль 08, 2010, 16:39 »

Код:
class MyDataModel : public QAbstractItemModel {
....
virtual void data( ..);  // добавить выдачу для Qt::BackgroundRole
...

void NextBlink( void ) { mBlinkState = (mBlinkState + 1) % 2; }

QVector <QModelIndex> mBlinkCell; // массив мигающих ячеек
int mBlinkState:                          // напр. 0 = синий, 1 = красный и.т.п.
};
По таймеру таблица говорит модели NextBlink и вызывает перерисовку нужных ячеек.
Правда, судя по исходникам, background (возвращаемый data) будет игнорироваться для выделенных ячеек если showDecorationSelected = true в стиле. Но оно public, так что можно напр. перекрыть paint для делегата. Короче, раскрасить ячейку можно  Улыбающийся
В этом варианте мигающие элементы придется хранить и во view(очень плохо). Или по сигналу таймера вызывать repaint().
Записан
crossly
Гость
« Ответ #14 : Февраль 08, 2010, 16:51 »

а вы не рассматривали вариант засовывания gif-анимации в делегат??
Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


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