November 7, 2010

Ayman Ayman
Lab Rat
13 posts

animate buttons

 

Hello,
I would like to animate my 4 QPushButton so when I click on button1 the state1 will be trigger, when I click on button2 this trigger state2 and the click on button3 trigger state3.

I tried and tried to do this but unsuccessful :(

my code is based on this Qt example: http://doc.trolltech.com/4.7/animation-moveblocks.html [doc.trolltech.com]

please help me to do this and if possible simplify me the code if it’s simplifiable because I don’t need the random state triggering as in the above Qt example

main.cpp

  1. #include <QtCore>
  2. #include <QtGui>
  3.  
  4. class StateSwitchEvent: public QEvent
  5. {
  6. public:
  7.  
  8.     StateSwitchEvent(int rand): QEvent(Type(StateSwitchType)), m_rand(rand)
  9.     {
  10.     }
  11.  
  12.     enum { StateSwitchType = QEvent::User + 256 };
  13.     int rand() const { return m_rand; }
  14.  
  15. private:
  16.     int m_rand;
  17. };
  18.  
  19.  
  20. class StateSwitchTransition: public QAbstractTransition
  21. {
  22. public:
  23.     StateSwitchTransition(int rand): QAbstractTransition(), m_rand(rand)
  24.     {
  25.     }
  26.  
  27. protected:
  28.     virtual bool eventTest(QEvent *event)
  29.     {
  30.         return (event->type() == QEvent::Type(StateSwitchEvent::StateSwitchType))
  31.             && (static_cast<StateSwitchEvent *>(event)->rand() == m_rand);
  32.     }
  33.  
  34.     virtual void onTransition(QEvent *) {}
  35.  
  36. private:
  37.     int m_rand;
  38. };
  39.  
  40. class StateSwitcher : public QState
  41. {
  42.     Q_OBJECT
  43. public:
  44.     StateSwitcher(QStateMachine *machine): QState(machine), m_stateCount(0), m_lastIndex(0)
  45.     { }
  46.  
  47.  
  48.     virtual void onEntry(QEvent *)
  49.     {
  50.         int n;
  51.         while ((n = (qrand() % m_stateCount + 1)) == m_lastIndex)
  52.         { }
  53.         m_lastIndex = n;
  54.         machine()->postEvent(new StateSwitchEvent(n));
  55.     }
  56.     virtual void onExit(QEvent *) {}
  57.  
  58.     void addState(QState *state, QAbstractAnimation *animation) {
  59.         StateSwitchTransition *trans = new StateSwitchTransition(++m_stateCount);
  60.         trans->setTargetState(state);
  61.         addTransition(trans);
  62.         trans->addAnimation(animation);
  63.     }
  64.  
  65. private:
  66.     int m_stateCount;
  67.     int m_lastIndex;
  68. };
  69.  
  70. QState *createGeometryState(QObject *w1, const QRect &rect1,
  71.                             QObject *w2, const QRect &rect2,
  72.                             QObject *w3, const QRect &rect3,
  73.                             QObject *w4, const QRect &rect4,
  74.                             QState *parent)
  75. {
  76.     QState *result = new QState(parent);
  77.     result->assignProperty(w1, "geometry", rect1);
  78.     result->assignProperty(w2, "geometry", rect2);
  79.     result->assignProperty(w3, "geometry", rect3);
  80.     result->assignProperty(w4, "geometry", rect4);
  81.  
  82.     return result;
  83. }
  84.  
  85. int main(int argc, char **argv)
  86. {
  87.     QApplication app(argc, argv);
  88.  
  89.     QWidget window;
  90.     QPalette palette;
  91.     palette.setBrush(QPalette::Window, Qt::black);
  92.     window.setPalette(palette);
  93.     QPushButton *button1 = new QPushButton("A", &window);
  94.     QPushButton *button2 = new QPushButton("B", &window);
  95.     QPushButton *button3 = new QPushButton("C", &window);
  96.     QPushButton *button4 = new QPushButton("D", &window);
  97.  
  98.     QStateMachine machine;
  99.  
  100.     QState *group = new QState();
  101.     QTimer timer;
  102.    // timer.setInterval(2000);
  103.    // timer.setSingleShot(true);
  104.    // QObject::connect(group, SIGNAL(entered()), &timer, SLOT(start()));
  105.  
  106.     QState *state1;
  107.     QState *state2;
  108.     QState *state3;
  109.  
  110.     state1 = createGeometryState(button1, QRect(8, 5, 50, 50), button2, QRect(66, 5, 50, 50), button3, QRect(124, 5, 50, 50), button4, QRect(182, 5, 50, 50), group);
  111.     state2 = createGeometryState(button1, QRect(8, 200, 50, 50), button2, QRect(66, 200, 50, 50), button3, QRect(124, 200, 50, 50), button4, QRect(182, 200, 50, 50), group);
  112.     state3 = createGeometryState(button1, QRect(150, 100, 50, 50), button2, QRect(100, 100, 50, 50), button3, QRect(50, 100, 50, 50), button4, QRect(0, 100, 50, 50), group);
  113.  
  114.     group->setInitialState(state1);
  115.  
  116.     QParallelAnimationGroup animationGroup;
  117.     QSequentialAnimationGroup *subGroup;
  118.  
  119.     QPropertyAnimation *anim = new QPropertyAnimation(button4, "geometry");
  120.     anim->setDuration(4000);
  121.     anim->setEasingCurve(QEasingCurve::OutElastic);
  122.     animationGroup.addAnimation(anim);
  123.  
  124.     subGroup = new QSequentialAnimationGroup(&animationGroup);
  125.     subGroup->addPause(100);
  126.     anim = new QPropertyAnimation(button3, "geometry");
  127.     anim->setDuration(4000);
  128.     anim->setEasingCurve(QEasingCurve::OutElastic);
  129.     subGroup->addAnimation(anim);
  130.  
  131.  
  132.     subGroup = new QSequentialAnimationGroup(&animationGroup);
  133.     subGroup->addPause(150);
  134.     anim = new QPropertyAnimation(button2, "geometry");
  135.     anim->setDuration(4000);
  136.     anim->setEasingCurve(QEasingCurve::OutElastic);
  137.     subGroup->addAnimation(anim);
  138.  
  139.     subGroup = new QSequentialAnimationGroup(&animationGroup);
  140.     subGroup->addPause(200);
  141.     anim = new QPropertyAnimation(button1, "geometry");
  142.     anim->setDuration(4000);
  143.     anim->setEasingCurve(QEasingCurve::OutElastic);
  144.     subGroup->addAnimation(anim);
  145.  
  146.  
  147.     StateSwitcher *stateSwitcher = new StateSwitcher(&machine);
  148.     group->addTransition(&timer, SIGNAL(timeout()), stateSwitcher);
  149.     stateSwitcher->addState(state1, &animationGroup);
  150.     stateSwitcher->addState(state2, &animationGroup);
  151.     stateSwitcher->addState(state3, &animationGroup);
  152.  
  153.     //QObject::connect(button1, SIGNAL(clicked()), &group, SLOT(stateSwitcher)); //I tried to connect button1 but unsuccessful and I don't know how connect it to state1
  154.  
  155.     machine.addState(group);
  156.     machine.setInitialState(group);
  157.     machine.start();
  158.  
  159.     window.resize(250, 250);
  160.     window.show();
  161.  
  162.     return app.exec();
  163. }
  164.  
  165. #include "main.moc"

thank you for your hep

1 reply

November 10, 2010

ad5xj ad5xj
Lab Rat
82 posts

If I understand your question correctly it may be simpler to connect the button click event to a state machine that makes the transition from one state to the other. Depending on which button was pressed, a different transition could be chosen in the connect.

That is assuming you want to go to the new state regardless of the order the buttons were clicked and regardless of the previous state.

If you want to change states in some predictable order you must always enter the state machine with the same transition and carry forward the destination state before exit.

From your description it seems more straightforward to start animation state machines (separate ones for each of the selected buttons) to do the animation and just use conventional signal/slot mechanics for the button clicks.

 Signature 

Ken AD5XJ

 
  ‹‹ [Solved] Adding new items to model (MVC)      [SOLVED] Hi, again :D Problem with Layouts... ››

You must log in to post a reply. Not a member yet? Register here!