Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: SpiritFire от Декабря 18, 2009, 16:54



Название: Анимированные layout (4.6)
Отправлено: SpiritFire от Декабря 18, 2009, 16:54
Скажите пожалуйста, есть ли возможность добавить анимацию к элементам, размеры и положение которых управляются layout-ом?

При беглом знакомстве анимацию-то добавить удалось, но работает она только в случае перемещения виджета из-за смены его состояния. Лейауты состояния не гоняют (что вполне логично) следовательно, анимации нет.

С другой стороны видел на ютубе что-то очень похожее на flow layout, с анимацией, к сожалению не могу дать линк - на работе мегоодмин запретил ютубы и подобные "баловства".

Добавлено потом: тыц -> http://www.youtube.com/watch?v=eJcTBJaPRZg (http://www.youtube.com/watch?v=eJcTBJaPRZg)


Название: Re: Анимированные layout (4.6)
Отправлено: niXman от Декабря 18, 2009, 18:06
для это есть Animation Framework


Название: Re: Анимированные layout (4.6)
Отправлено: SpiritFire от Декабря 18, 2009, 18:29
для это есть Animation Framework
Благодарю, ваша помощь неоценима.
Как видно из моего предыдущего поста - я знаю о существовании Animation Framework. Более того, я достаточно подробно изучил документацию по нему и постепенно прихожу к выводу о том, что скорее всего, лейауты не поддерживают анимацию.

Уточню вопрос:
1. Скажите пожалуйста, прав ли я, что невозможно к стандартным лейаутам прикрутить анимацию, кроме изврещений, за использование которых нужно отбивать руки сочинителям.

2. Если я не прав, подскажите пожалуйста, куда копать в сторону интеграции лейаутов и анимации.

3. Что требуется: при изменении размера формы дочерние элементы плавно "ехают" на новое место.


Название: Re: Анимированные layout (4.6)
Отправлено: Dendy от Декабря 18, 2009, 18:34
Думаю для этого нужно унаследоваться от QLayout и по таймеру возить окна по родителю.


Название: Re: Анимированные layout (4.6)
Отправлено: SpiritFire от Декабря 18, 2009, 19:16
Думаю, да. Пришел к выводу о том, что стандартные лейауты изменяют свойства "размер" и "позиция" используя невиртуальные методы QWidget::resize, QWidget::move. При этом свойство менется мгновенно. Для того, чтобы оно менялось не мгновенно (с анимацией), есть насколько вариантов - менять, через QPropertyAnimation, переопределять move, resize. Последнее отпадает, так как методы невиртуальные.

Можно конечно как-то сделать через таймеры, но хотелось бы не одноразовое решение. Вывод - для общего решения придется писать свой лейаут, который будет менять значения нужных полей через QPropertyAnimation.


Название: Re: Анимированные layout (4.6)
Отправлено: Kolobok от Декабря 19, 2009, 14:22
Проще написать отдельный класс, который берет данные из лейоута и управляет анимацией.
Кроме того, самописные лейоуты нельзя использовать в дизайнере. Я, во всяком случае, не нашел как.


Название: Re: Анимированные layout (4.6)
Отправлено: SpiritFire от Декабря 20, 2009, 00:10
В общем, разобрася. Когда лэйаут пересчитывает геометрию всех входящих в него итемов, он, что логично, выполняет что-то вроде

Код:
foreach( QLayoutItem* item, items)
    item->setGeometry( newGeometry );

При этом метод QLayoutItem::setGeometry(...) виртуальный. Сюда и надо копать. Оказывается, при добавлении виджета (пока анимировал только размеры виджетов, не дочерних лейаутов, хоть это не принципиально) создается его класс-потомок QWidgetItem : public QLayoutItem... Или новоиспеченный AnimatedWidgetItem : public QWidgetItem. Вот и вся хитрость.

Стандартный ВиджетИтем изменяет геометрию через вызов QWidget::setGeometry.
Новый обработчик изменяет геометрию в соответствии с моими религиозными убеждениями, которые я подробно изложил в своей реализации AnimatedWidgetItem::setGeometry =) А там все просто: позаимствовал часть кода из стандартного обработчика, но геометрию меняю через QPropertyAnimation. Все...

Что имеем: пользоваться дизайнером можно, лейауты стандартные, виджеты тоже абсолютно стандартные.... Единственное но: будут анимированы только виджеты, добавленные динамически через layut->addItem( new AnimatedWidgetItem(widget, peremeters) );

Если нужно, могу поделиться сорцами, это не военная тайна )



Название: Re: Анимированные layout (4.6)
Отправлено: Dendy от Декабря 20, 2009, 00:53
Делись, очень интересно посмотреть (-;


Название: Re: Анимированные layout (4.6)
Отправлено: Gorthauer от Декабря 20, 2009, 12:11
Ну у меня была нужда сделать анимацию лишь при появлении виджета, поэтому я на время анимации просто отключил лэйаут


Название: Re: Анимированные layout (4.6)
Отправлено: NicK от Декабря 23, 2009, 09:50
В общем, разобрася. Когда лэйаут пересчитывает геометрию всех входящих в него итемов, он, что логично, выполняет что-то вроде

Код:
foreach( QLayoutItem* item, items)
    item->setGeometry( newGeometry );

При этом метод QLayoutItem::setGeometry(...) виртуальный. Сюда и надо копать. Оказывается, при добавлении виджета (пока анимировал только размеры виджетов, не дочерних лейаутов, хоть это не принципиально) создается его класс-потомок QWidgetItem : public QLayoutItem... Или новоиспеченный AnimatedWidgetItem : public QWidgetItem. Вот и вся хитрость.

Стандартный ВиджетИтем изменяет геометрию через вызов QWidget::setGeometry.
Новый обработчик изменяет геометрию в соответствии с моими религиозными убеждениями, которые я подробно изложил в своей реализации AnimatedWidgetItem::setGeometry =) А там все просто: позаимствовал часть кода из стандартного обработчика, но геометрию меняю через QPropertyAnimation. Все...

Что имеем: пользоваться дизайнером можно, лейауты стандартные, виджеты тоже абсолютно стандартные.... Единственное но: будут анимированы только виджеты, добавленные динамически через layut->addItem( new AnimatedWidgetItem(widget, peremeters) );

Если нужно, могу поделиться сорцами, это не военная тайна )



Очень нужно. поделитесь, пожалуйста, исходниками.


Название: Re: Анимированные layout (4.6)
Отправлено: SpiritFire от Декабря 28, 2009, 03:49
Извините, что так длго не отвечал - не было времени.

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

помогает следующий хак:

Код:
layout->addWidget( widget );   // добавление
layout->itemAt( layout->count-1 ); // извлечение его же
layout->addItem( new AnimatedWidgetItem(widget, peremeters) );  // снова добавление

Если кто найдет точно из-за чего так происходит - буду премного благодарен :) Ну а так юзайте на здоровье)

Во вложении простейший проект для VS2008, на работе подобное легко собирал на Креаторе+МинГВ.


Название: Re: Анимированные layout (4.6)
Отправлено: SABROG от Января 05, 2010, 18:09
Ниче так

(http://img691.imageshack.us/img691/7443/animlays.gif)


Название: Re: Анимированные layout (4.6)
Отправлено: BlackTass от Января 06, 2010, 14:59
Ниче так

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


Название: Re: Анимированные layout (4.6)
Отправлено: SABROG от Января 06, 2010, 15:15
Хотелось бы посмотреть как это всё будет работать на перегруженном контролами интерфейсе :)

У меня в фирме с некоторого времени все сотрудники были переведены на работу через удаленный рабочий стол (remote desktop), т.к. сервак находится в дата центре весь траффик идет через интернет. И я с некоторым разочарованием смотрю на тормоза моих программ, где применялась анимация, спец эффекты и тому подобное. Так что тут либо шашечки, либо ехать. Полагаю разработчики должны вводить какие либо настройки отключающие специальные эффекты.


Название: Re: Анимированные layout (4.6)
Отправлено: Igors от Января 06, 2010, 16:26
По-моему это хороший feature request для Qt


Название: Re: Анимированные layout (4.6)
Отправлено: revers от Января 10, 2010, 16:10
Эээ... вроде есть уже давно QGraphicsLayout. Ну и статья (http://blog.eduardofleury.com/archives/2009/02/51/) с демонстрационным видео


Название: Re: Анимированные layout (4.6)
Отправлено: aljeshishe от Января 13, 2010, 19:51
Эээ... вроде есть уже давно QGraphicsLayout. Ну и статья (http://blog.eduardofleury.com/archives/2009/02/51/) с демонстрационным видео
Тут как раз тоже самое и сделано
Цитировать
Animated Layout Proxy that sits between the Layout and each of the child widgets
The trick here is that rather than sending the geometry change request immediatelly, the Proxy creates a QAnimation from the former state to the new one.
На QGraphicsLayout'е конечно это все побыстрее работать должно...
Ну и пример там "поживописнее".