Название: QStateMachine, QPropertyAnimation feat resizeEvent (...)
Отправлено: Ice_Bear от Март 14, 2013, 19:42
Здравствуйте,
есть QMainWindow в него вставлены два виджета, которые должны отображаться поочереди (сначала один, затем другой). Переход между виджетами осуществляется посредством QstateMachine и QPropertyAnimation. Я не смог найти как в данном случае правильно реализовать событие resizeEvent (QResizeEvent *) так, чтобы соответственно размеру окна изменялась геометрия состояний QStateMachine.
Если тупо пересчитать геометрию состояний, перегружая resizeEvent (QResizeEvent *), то все вроде бы работает правильно, но … только на первый взгляд — при изменении размеров QMainWindow, когда процесс анимации еще идет (виджет перемещается по экрану) размеры не пересчитываются. Метод fitInView в QMainWindow не нашел.
спасибо,
Название: Re: QStateMachine, QPropertyAnimation feat resizeEvent (...)
Отправлено: Bepec от Март 14, 2013, 20:08
Как вариант останавливать анимацию при перетаскивании и изменении размера.
Ну или если есть возможность, продолжать анимацию, но убивая старую и создавая новую на перерасчитанные координаты.
Название: Re: QStateMachine, QPropertyAnimation feat resizeEvent (...)
Отправлено: Ice_Bear от Март 15, 2013, 13:16
спасибо большое за ответ, а есть может какой-нибудь пример, иллюстрирующий как эту проблему рекомендуют решать разработчики? К сожалению, я в примерах и демосах не нашел аналогичной ситуации
спасибо,
Название: Re: QStateMachine, QPropertyAnimation feat resizeEvent (...)
Отправлено: Bepec от Март 15, 2013, 13:21
Пример в экзамплах Animation framework -> states. При нажатии кнопки передвигаются иконки. При быстром нажатии видно, что они летят туда, потом при нажатии на следующее место, при следующем - уже за экран убираются. Реал тайм так сказать.
Название: Re: QStateMachine, QPropertyAnimation feat resizeEvent (...)
Отправлено: Ice_Bear от Март 18, 2013, 08:45
я посмотрел еще раз этот пример как Вы сказали, там все прикрепляется к GraphicsView, также при масштабировании там не просто увеличивается размер элементов интерфейса - они масштабируются вместе с содержимым, как будто они являются пассивной картинкой,
Название: Re: QStateMachine, QPropertyAnimation feat resizeEvent (...)
Отправлено: Bepec от Март 18, 2013, 09:08
выложите пример с данной проблемой и тестовым методом, её показывающим.
Название: Re: QStateMachine, QPropertyAnimation feat resizeEvent (...)
Отправлено: Ice_Bear от Март 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];
спасибо
Название: Re: QStateMachine, QPropertyAnimation feat resizeEvent (...)
Отправлено: Ice_Bear от Март 25, 2013, 13:08
ключевые места приведенного отрезка кода - консруктор класса DataViewer b функция resizeEven
спасибо
|