kenouz1234
7th November 2010, 15:29
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
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
#include <QtCore>
#include <QtGui>
class StateSwitchEvent: public QEvent
{
public:
StateSwitchEvent(int rand): QEvent(Type(StateSwitchType)), m_rand(rand)
{
}
enum { StateSwitchType = QEvent::User + 256 };
int rand() const { return m_rand; }
private:
int m_rand;
};
class StateSwitchTransition: public QAbstractTransition
{
public:
StateSwitchTransition(int rand): QAbstractTransition(), m_rand(rand)
{
}
protected:
virtual bool eventTest(QEvent *event)
{
return (event->type() == QEvent::Type(StateSwitchEvent::StateSwitchType))
&& (static_cast<StateSwitchEvent *>(event)->rand() == m_rand);
}
virtual void onTransition(QEvent *) {}
private:
int m_rand;
};
class StateSwitcher : public QState
{
Q_OBJECT
public:
StateSwitcher(QStateMachine *machine): QState(machine), m_stateCount(0), m_lastIndex(0)
{ }
virtual void onEntry(QEvent *)
{
int n;
while ((n = (qrand() % m_stateCount + 1)) == m_lastIndex)
{ }
m_lastIndex = n;
machine()->postEvent(new StateSwitchEvent(n));
}
virtual void onExit(QEvent *) {}
void addState(QState *state, QAbstractAnimation *animation) {
StateSwitchTransition *trans = new StateSwitchTransition(++m_stateCount);
trans->setTargetState(state);
addTransition(trans);
trans->addAnimation(animation);
}
private:
int m_stateCount;
int m_lastIndex;
};
QState *createGeometryState(QObject *w1, const QRect &rect1,
QObject *w2, const QRect &rect2,
QObject *w3, const QRect &rect3,
QObject *w4, const QRect &rect4,
QState *parent)
{
QState *result = new QState(parent);
result->assignProperty(w1, "geometry", rect1);
result->assignProperty(w2, "geometry", rect2);
result->assignProperty(w3, "geometry", rect3);
result->assignProperty(w4, "geometry", rect4);
return result;
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget window;
QPalette palette;
palette.setBrush(QPalette::Window, Qt::black);
window.setPalette(palette);
QPushButton *button1 = new QPushButton("A", &window);
QPushButton *button2 = new QPushButton("B", &window);
QPushButton *button3 = new QPushButton("C", &window);
QPushButton *button4 = new QPushButton("D", &window);
QStateMachine machine;
QState *group = new QState();
QTimer timer;
// timer.setInterval(2000);
// timer.setSingleShot(true);
// QObject::connect(group, SIGNAL(entered()), &timer, SLOT(start()));
QState *state1;
QState *state2;
QState *state3;
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);
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);
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);
group->setInitialState(state1);
QParallelAnimationGroup animationGroup;
QSequentialAnimationGroup *subGroup;
QPropertyAnimation *anim = new QPropertyAnimation(button4, "geometry");
anim->setDuration(4000);
anim->setEasingCurve(QEasingCurve::OutElastic);
animationGroup.addAnimation(anim);
subGroup = new QSequentialAnimationGroup(&animationGroup);
subGroup->addPause(100);
anim = new QPropertyAnimation(button3, "geometry");
anim->setDuration(4000);
anim->setEasingCurve(QEasingCurve::OutElastic);
subGroup->addAnimation(anim);
subGroup = new QSequentialAnimationGroup(&animationGroup);
subGroup->addPause(150);
anim = new QPropertyAnimation(button2, "geometry");
anim->setDuration(4000);
anim->setEasingCurve(QEasingCurve::OutElastic);
subGroup->addAnimation(anim);
subGroup = new QSequentialAnimationGroup(&animationGroup);
subGroup->addPause(200);
anim = new QPropertyAnimation(button1, "geometry");
anim->setDuration(4000);
anim->setEasingCurve(QEasingCurve::OutElastic);
subGroup->addAnimation(anim);
StateSwitcher *stateSwitcher = new StateSwitcher(&machine);
group->addTransition(&timer, SIGNAL(timeout()), stateSwitcher);
stateSwitcher->addState(state1, &animationGroup);
stateSwitcher->addState(state2, &animationGroup);
stateSwitcher->addState(state3, &animationGroup);
//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
machine.addState(group);
machine.setInitialState(group);
machine.start();
window.resize(250, 250);
window.show();
return app.exec();
}
#include "main.moc"
thank you for your hep
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
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
#include <QtCore>
#include <QtGui>
class StateSwitchEvent: public QEvent
{
public:
StateSwitchEvent(int rand): QEvent(Type(StateSwitchType)), m_rand(rand)
{
}
enum { StateSwitchType = QEvent::User + 256 };
int rand() const { return m_rand; }
private:
int m_rand;
};
class StateSwitchTransition: public QAbstractTransition
{
public:
StateSwitchTransition(int rand): QAbstractTransition(), m_rand(rand)
{
}
protected:
virtual bool eventTest(QEvent *event)
{
return (event->type() == QEvent::Type(StateSwitchEvent::StateSwitchType))
&& (static_cast<StateSwitchEvent *>(event)->rand() == m_rand);
}
virtual void onTransition(QEvent *) {}
private:
int m_rand;
};
class StateSwitcher : public QState
{
Q_OBJECT
public:
StateSwitcher(QStateMachine *machine): QState(machine), m_stateCount(0), m_lastIndex(0)
{ }
virtual void onEntry(QEvent *)
{
int n;
while ((n = (qrand() % m_stateCount + 1)) == m_lastIndex)
{ }
m_lastIndex = n;
machine()->postEvent(new StateSwitchEvent(n));
}
virtual void onExit(QEvent *) {}
void addState(QState *state, QAbstractAnimation *animation) {
StateSwitchTransition *trans = new StateSwitchTransition(++m_stateCount);
trans->setTargetState(state);
addTransition(trans);
trans->addAnimation(animation);
}
private:
int m_stateCount;
int m_lastIndex;
};
QState *createGeometryState(QObject *w1, const QRect &rect1,
QObject *w2, const QRect &rect2,
QObject *w3, const QRect &rect3,
QObject *w4, const QRect &rect4,
QState *parent)
{
QState *result = new QState(parent);
result->assignProperty(w1, "geometry", rect1);
result->assignProperty(w2, "geometry", rect2);
result->assignProperty(w3, "geometry", rect3);
result->assignProperty(w4, "geometry", rect4);
return result;
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget window;
QPalette palette;
palette.setBrush(QPalette::Window, Qt::black);
window.setPalette(palette);
QPushButton *button1 = new QPushButton("A", &window);
QPushButton *button2 = new QPushButton("B", &window);
QPushButton *button3 = new QPushButton("C", &window);
QPushButton *button4 = new QPushButton("D", &window);
QStateMachine machine;
QState *group = new QState();
QTimer timer;
// timer.setInterval(2000);
// timer.setSingleShot(true);
// QObject::connect(group, SIGNAL(entered()), &timer, SLOT(start()));
QState *state1;
QState *state2;
QState *state3;
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);
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);
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);
group->setInitialState(state1);
QParallelAnimationGroup animationGroup;
QSequentialAnimationGroup *subGroup;
QPropertyAnimation *anim = new QPropertyAnimation(button4, "geometry");
anim->setDuration(4000);
anim->setEasingCurve(QEasingCurve::OutElastic);
animationGroup.addAnimation(anim);
subGroup = new QSequentialAnimationGroup(&animationGroup);
subGroup->addPause(100);
anim = new QPropertyAnimation(button3, "geometry");
anim->setDuration(4000);
anim->setEasingCurve(QEasingCurve::OutElastic);
subGroup->addAnimation(anim);
subGroup = new QSequentialAnimationGroup(&animationGroup);
subGroup->addPause(150);
anim = new QPropertyAnimation(button2, "geometry");
anim->setDuration(4000);
anim->setEasingCurve(QEasingCurve::OutElastic);
subGroup->addAnimation(anim);
subGroup = new QSequentialAnimationGroup(&animationGroup);
subGroup->addPause(200);
anim = new QPropertyAnimation(button1, "geometry");
anim->setDuration(4000);
anim->setEasingCurve(QEasingCurve::OutElastic);
subGroup->addAnimation(anim);
StateSwitcher *stateSwitcher = new StateSwitcher(&machine);
group->addTransition(&timer, SIGNAL(timeout()), stateSwitcher);
stateSwitcher->addState(state1, &animationGroup);
stateSwitcher->addState(state2, &animationGroup);
stateSwitcher->addState(state3, &animationGroup);
//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
machine.addState(group);
machine.setInitialState(group);
machine.start();
window.resize(250, 250);
window.show();
return app.exec();
}
#include "main.moc"
thank you for your hep