I hace a fullscreen program with several screens, and I want to go for one screen to the next one witht an slideshow animation.

I have a fullscreeen QMainWidget, with a placeholder VerticalLayout, where I put different QWidgets that act as "screens" for my application, one at a time. The user interacts with the current screen, and when it's time to go to the next one, I remove the current page from the vertical layout and place the new page instead.

It works flawlessly, but I want to spice it up with some QPropertyAnimation. I want to transition from one page to the next one with a little slideshow animation. I'm using the "geometry" property, to move both the old page and the new page, right-to-left. This is my code:

Qt Code:
  1. if (m_currentPage && animate)
  2. {
  3. // Don't allow the user to interact with the old page as it's being carried away
  4. m_currentPage->setEnabled(false);
  5.  
  6. QRect a = ui->placeholder->geometry();
  7. QRect b = QRect(a.width(), a.y(), a.width(), a.height());
  8. QRect c = QRect(-a.width(), a.y(), a.width(), a.height());
  9.  
  10. int animationDuration = 400;
  11.  
  12. QPropertyAnimation *animation = new QPropertyAnimation(m_currentPage, "geometry", this);
  13. animation->setStartValue(a);
  14. animation->setEndValue(direction == Forward ? c : b);
  15. animation->setDuration(animationDuration);
  16. animation->setEasingCurve(QEasingCurve::OutQuad);
  17. animation->start();
  18. connect(animation, SIGNAL(finished()), m_currentPage, SLOT(deleteLater()));
  19.  
  20. QPropertyAnimation *animation2 = new QPropertyAnimation(newPage, "geometry", this);
  21. animation2->setStartValue(direction == Forward ? b : c);
  22. animation2->setEndValue(a);
  23. animation2->setDuration(animationDuration);
  24. animation2->setEasingCurve(QEasingCurve::OutQuad);
  25. animation2->start();
  26. connect(animation2, SIGNAL(finished()), newPage, SLOT(setFocus()));
  27. }
  28. else
  29. {
  30. // Remove previous page
  31. clearLayout(ui->placeholder);
  32. }
  33.  
  34. // Set new page
  35. newPage->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  36. ui->placeholder->addWidget(newPage);
  37. newPage->setFocus();
  38.  
  39. connect(newPage,
  40. SIGNAL(setPage(KioskPage*,KioskMainWindow::Direction)),
  41. SLOT(setPage(KioskPage*,KioskMainWindow::Direction)));
  42. newPage->init();
  43.  
  44. m_currentPage = newPage;
  45.  
  46. languageChange();
  47.  
  48. if (animate)
  49. {
  50. newPage->hide();
  51. QTimer::singleShot(100, newPage, SLOT(show()));
  52. }
To copy to clipboard, switch view to plain text mode 

It works fairly well, but has one annoying bug: after this code is run, the function quits, the control returns to Qt internals and windows start to be drawn, what I see is, first, the newPage flickers once all over the m_currentPage, just for a fraction of a second, and then it disappears and the animation starts smoothly. I've tried a lot of stuff here, and that ugly QTimer::singleShot(100, newPage, SLOT(show())); is the only thing that appears to at least disguise part of the problem, but not completely. As soon as the show() slot is called, newPage flickers once over m_currentPage, disappears and appears again where it should be according to the QPropertyAnimation.

Does anyone know why this is happening, and what I could do to avoid it?