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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QStateMachine, QPropertyAnimation feat resizeEvent (...)  (Прочитано 5708 раз)
Ice_Bear
Гость
« : Март 14, 2013, 19:42 »

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

есть QMainWindow в него вставлены два виджета, которые должны отображаться поочереди (сначала один, затем другой). Переход между виджетами осуществляется посредством QstateMachine и QPropertyAnimation. Я не смог найти как в данном случае правильно реализовать событие resizeEvent (QResizeEvent *) так, чтобы соответственно размеру окна изменялась геометрия состояний QStateMachine.

Если тупо пересчитать геометрию состояний, перегружая resizeEvent (QResizeEvent *), то все вроде бы работает правильно, но … только на первый взгляд — при изменении размеров  QMainWindow, когда процесс анимации еще идет (виджет перемещается по экрану) размеры не пересчитываются. Метод fitInView в  QMainWindow не нашел.


спасибо,
Записан
Bepec
Гость
« Ответ #1 : Март 14, 2013, 20:08 »

Как вариант останавливать анимацию при перетаскивании и изменении размера.

Ну или если есть возможность, продолжать анимацию, но убивая старую и создавая новую на перерасчитанные координаты.
Записан
Ice_Bear
Гость
« Ответ #2 : Март 15, 2013, 13:16 »

спасибо большое за ответ, а есть может какой-нибудь пример, иллюстрирующий как эту проблему рекомендуют решать разработчики? К сожалению, я в примерах и демосах не нашел аналогичной ситуации

спасибо,
Записан
Bepec
Гость
« Ответ #3 : Март 15, 2013, 13:21 »

Пример в экзамплах Animation framework -> states. При нажатии кнопки передвигаются иконки. При быстром нажатии видно, что они летят туда, потом при нажатии на следующее место, при следующем - уже за экран убираются. Реал тайм так сказать.
Записан
Ice_Bear
Гость
« Ответ #4 : Март 18, 2013, 08:45 »

я посмотрел еще раз этот пример как Вы сказали, там все прикрепляется к GraphicsView, также при масштабировании там не просто увеличивается размер элементов интерфейса - они масштабируются вместе с содержимым, как будто они являются пассивной картинкой,

Записан
Bepec
Гость
« Ответ #5 : Март 18, 2013, 09:08 »

выложите пример с данной проблемой и тестовым методом, её показывающим.
Записан
Ice_Bear
Гость
« Ответ #6 : Март 25, 2013, 13:07 »

Здравствуйте снова,

изучил проблему чуть подробнее, за то время, пока не писал - ее можно свести к следующему:

при смене состояния QStateMachine, переходом QAbstractTransition из одного состояния в другое, значения этих состояний изменить нельзя, остановка в начале и запуск машины в конце resizeEvent ничего не дают.

во всех примерах от Qt изменение размеров окна при анимации обрабатывается QGraphicsView::fitInView


вот вкратце код:

Код:
static QState * _calc_png_state (QState * state, Ui_LungsWindow * ui_lungs)
{
QRectF rect = ui_lungs -> centralwidget -> geometry ();
state -> assignProperty (ui_lungs -> graphicsView,
"geometry",
rect
);
rect.moveLeft (rect.width ());
state -> assignProperty (ui_lungs -> widget,
"geometry",
rect
);
return state;
}


static QState * _calc_plot_state (QState * state, Ui_LungsWindow * ui_lungs)
{
QRectF rect = ui_lungs -> centralwidget -> geometry ();
state -> assignProperty (ui_lungs -> widget,
"geometry",
rect
);
rect.moveRight (rect.x ());
state -> assignProperty (ui_lungs -> graphicsView,
"geometry",
rect
);
return state;
}

static QPropertyAnimation *  _png_animation
(QAbstractTransition * transition, Ui_LungsWindow * ui_lungs)
{
QPropertyAnimation * png_out =
new QPropertyAnimation (ui_lungs -> graphicsView,
"geometry"
);
png_out -> setDuration (3500);

QEasingCurve curve (QEasingCurve :: OutElastic);
qDebug () << curve.period () << " " << curve.amplitude ();

curve.setPeriod (0.5);
curve.setAmplitude (0.7);

png_out -> setEasingCurve (curve);

transition -> addAnimation (png_out);

QPropertyAnimation * plot_in =
new QPropertyAnimation (ui_lungs -> widget,
"geometry"
);
plot_in -> setDuration (3500);
plot_in -> setEasingCurve (curve);

transition -> addAnimation (plot_in);

return png_out;
}

QPropertyAnimation * _plot_animation
(QAbstractTransition * transition, Ui_LungsWindow * ui_lungs)
{
QPropertyAnimation * plot_out =
new QPropertyAnimation (ui_lungs -> graphicsView,
"geometry"
);
plot_out -> setDuration (9000);
transition -> addAnimation (plot_out);

QPropertyAnimation * png_in =
new QPropertyAnimation (ui_lungs -> widget,
"geometry"
);
png_in -> setDuration (1000);
transition -> addAnimation (png_in);

return plot_out;
}

const char * name [] = { "groupBox", "groupBox_2", "groupBox_3", "groupBox_4" };

DataViewer :: DataViewer ()
{
    (_ui_lungs = new Ui_LungsWindow) -> setupUi (this);
   
// создаю два состояния для QStateMachine
_png  = _calc_png_state (new QState (), _ui_lungs);
_plot = _calc_plot_state (new QState (), _ui_lungs);

_machine.addState (_png);
_machine.addState (_plot);

// добавляю переходы, к ним анимацию
QAbstractTransition * png_trans =
_png -> addTransition (this, SIGNAL (_switch_view ()), _plot);
a1 = _png_animation (png_trans, _ui_lungs);

QAbstractTransition * plot_trans =
_plot -> addTransition (this, SIGNAL (_switch_view ()), _png);
a2 = _plot_animation (plot_trans, _ui_lungs);

_machine.setInitialState (_png);
_machine.start ();
}

# include <QVector>

 void DataViewer :: keyPressEvent (QKeyEvent * event)
{
    switch ( event -> key () ) {
case Qt :: Key_Space :
emit _switch_view ();
break;
default :
QWidget :: keyPressEvent (event);
}
}

//вот камень преткновения - не могу сделать так, чтобы если пользователь изменит размеры окна, когда анимация происходит - она отрабатывала правильно
void DataViewer :: resizeEvent (QResizeEvent * event)
    {
QMainWindow :: resizeEvent (event);

//пересчет состояний на новые размеры, при следующем переходе используются правильные размеры,
в текущем - предыдущие, т.е. неправитльные
_calc_png_state (_png, _ui_lungs);
_calc_plot_state (_plot, _ui_lungs);

QRectF r = t1 -> targetState () -> property ("geometry").toRectF ();

emit _switch_view ();
emit _switch_view ();

//изменяю размеры и позицию текущих состояний виджетов
_ui_lungs -> graphicsView -> resize (event -> size ());
_ui_lungs -> widget -> resize (event -> size ());


//код относится также к размерам и позиционированию виджетов, написан на скорую руку, поэтому плохо структурирован
int dx = event -> size ().width () - event -> oldSize ().width ();
if (_ui_lungs -> graphicsView -> geometry ().x () == _ui_lungs -> centralwidget -> geometry ().x ()) {
QRect  r = _ui_lungs -> widget -> geometry ();
r.moveLeft (r.x () + dx);
_ui_lungs -> widget -> setGeometry (r);
}


if (_ui_lungs -> widget -> geometry ().x () == _ui_lungs -> centralwidget -> geometry ().x ()) {
QRect  r = _ui_lungs -> graphicsView -> geometry ();
r.moveLeft (r.x () - dx);
_ui_lungs -> graphicsView -> setGeometry (r);
}


// QMainWindow :: resizeEvent (event);
    }

void DataViewer :: add_SimpleGraphicsTextItem (TextMonitor * tm)
{
QGraphicsSimpleTextItem * t = tm -> graphicsSimpleTextItem ();
_ui_lungs -> graphicsView -> scene () -> addItem (t);
}

PlotMonitor * DataViewer :: plot (int i)
{
return _plot_monitor [i];

спасибо
Записан
Ice_Bear
Гость
« Ответ #7 : Март 25, 2013, 13:08 »

ключевые места приведенного отрезка кода - консруктор класса DataViewer b функция resizeEven

спасибо
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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