StackedWidget.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include "StackedWidget.h"
  2. #include <QDebug>
  3. OpacityAniStackedWidget::OpacityAniStackedWidget(QWidget *parent) : QStackedWidget(parent), m_nextIndex(0) { }
  4. void OpacityAniStackedWidget::addWidget(QWidget *w)
  5. {
  6. QStackedWidget::addWidget(w);
  7. QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(this);
  8. effect->setOpacity(1);
  9. QPropertyAnimation *ani = new QPropertyAnimation(effect, "opacity", this);
  10. ani->setDuration(220);
  11. connect(ani, &QPropertyAnimation::finished, this, &OpacityAniStackedWidget::onAniFinished);
  12. m_anis << ani;
  13. m_effects << effect;
  14. w->setGraphicsEffect(effect);
  15. }
  16. void OpacityAniStackedWidget::setCurrentIndex(int index)
  17. {
  18. int i = this->currentIndex();
  19. if (index == i) {
  20. return;
  21. }
  22. QPropertyAnimation *ani = nullptr;
  23. if (index > i) {
  24. ani = m_anis[index];
  25. ani->setStartValue(0);
  26. ani->setEndValue(1);
  27. QStackedWidget::setCurrentIndex(index);
  28. } else {
  29. ani = m_anis[index];
  30. ani->setStartValue(1);
  31. ani->setEndValue(0);
  32. }
  33. this->widget(i)->show();
  34. m_nextIndex = index;
  35. }
  36. void OpacityAniStackedWidget::setCurrentWidget(QWidget *w)
  37. {
  38. this->setCurrentIndex(this->indexOf(w));
  39. }
  40. void OpacityAniStackedWidget::onAniFinished()
  41. {
  42. QStackedWidget::setCurrentIndex(m_nextIndex);
  43. }
  44. PopUpAniStackedWidget::PopUpAniStackedWidget(QWidget *parent) : QStackedWidget(parent), m_nextIndex(-1), m_ani(nullptr)
  45. {
  46. }
  47. /**
  48. * @brief add widget to window
  49. * @param widget: widget to be added
  50. * @param deltaX: the x-axis offset from the beginning to the end of animation
  51. * @param deltaY: the y-axis offset from the beginning to the end of animation
  52. */
  53. void PopUpAniStackedWidget::addWidget(QWidget *widget, int deltaX, int deltaY)
  54. {
  55. QStackedWidget::addWidget(widget);
  56. m_aniInfos << PopUpAniInfo(widget, deltaX, deltaY, new QPropertyAnimation(widget, "pos"));
  57. }
  58. /**
  59. * @brief set current window to display
  60. * @param index: the index of widget to display
  61. * @param needPopOut: need pop up animation or not
  62. * @param showNextWidgetDirectly: whether to show next widget directly when animation started
  63. * @param duration: animation duration
  64. * @param easingCurve: the interpolation mode of animation
  65. */
  66. void PopUpAniStackedWidget::setCurrentIndex(int index, bool needPopOut, bool showNextWidgetDirectly, int duration,
  67. QEasingCurve easingCurve)
  68. {
  69. if (index < 0 || index >= this->count()) {
  70. qCritical() << QString("The index `%1` is illegal").arg(index);
  71. return;
  72. }
  73. if (index == this->currentIndex()) {
  74. return;
  75. }
  76. if (m_ani && m_ani->state() == QAbstractAnimation::Running) {
  77. m_ani->stop();
  78. onAniFinished();
  79. }
  80. // get the index of widget to be displayed
  81. m_nextIndex = index;
  82. // get animation
  83. PopUpAniInfo nextAniInfo = m_aniInfos[index];
  84. PopUpAniInfo currentAniInfo = m_aniInfos[this->currentIndex()];
  85. QWidget *currentWidget = this->currentWidget();
  86. QWidget *nextWidget = nextAniInfo.widget;
  87. QPropertyAnimation *ani = needPopOut ? currentAniInfo.ani : nextAniInfo.ani;
  88. m_ani = ani;
  89. if (needPopOut) {
  90. int deltaX = currentAniInfo.deltaX;
  91. int deltaY = currentAniInfo.deltaY;
  92. QPoint pos = currentWidget->pos() + QPoint(deltaX, deltaY);
  93. setAnimation(ani, currentWidget->pos(), pos, duration, easingCurve);
  94. nextWidget->setVisible(showNextWidgetDirectly);
  95. } else {
  96. int deltaX = nextAniInfo.deltaX;
  97. int deltaY = nextAniInfo.deltaY;
  98. QPoint pos = nextWidget->pos() + QPoint(deltaX, deltaY);
  99. setAnimation(ani, pos, QPoint(nextWidget->x(), this->y()), duration, easingCurve);
  100. QStackedWidget::setCurrentIndex(index);
  101. }
  102. // start animation
  103. connect(ani, &QPropertyAnimation::finished, this, &PopUpAniStackedWidget::onAniFinished);
  104. ani->start();
  105. emit aniStart();
  106. }
  107. /**
  108. * @brief set currect widget
  109. * @param widget: the widget to be displayed
  110. * @param needPopOut: need pop up animation or not
  111. * @param showNextWidgetDirectly: whether to show next widget directly when animation started
  112. * @param duration: animation duration
  113. * @param easingCurve: the interpolation mode of animation
  114. */
  115. void PopUpAniStackedWidget::setCurrentWidget(QWidget *widget, bool needPopOut, bool showNextWidgetDirectly,
  116. int duration, QEasingCurve easingCurve)
  117. {
  118. this->setCurrentIndex(this->indexOf(widget), needPopOut, showNextWidgetDirectly, duration, easingCurve);
  119. }
  120. /// set the config of animation
  121. void PopUpAniStackedWidget::setAnimation(QPropertyAnimation *ani, const QPoint &startValue, const QPoint &endValue,
  122. int duration, QEasingCurve easingCurve)
  123. {
  124. ani->setEasingCurve(easingCurve);
  125. ani->setStartValue(startValue);
  126. ani->setEndValue(endValue);
  127. ani->setDuration(duration);
  128. }
  129. void PopUpAniStackedWidget::onAniFinished() { }