转载自: meego中文论坛-米趣网
这里再介绍Qt-4.6中提供的状态机框架,它为实现复杂的动画效果提供了一个方便的接口。
在接触代码前,先来看一个简单的状态机图(利用Linux工具Dia完成)
状 态机顾名思义,应该有不同的状态在切换。上面状态机图中,我们提供了两种状态state1和state2。而状态的区分是由状态的属性来描述的,比如 p1,p2…等等。从一个状态到另一个状态的转化,必须由触发条件来完成,上图state1到state2的状态转换由transition1来表 示,state2到state1的状态转换由transition2来表示。如果希望在状态转换过程中有动画来展示,那么可以在transition1和 transition2中加入动画效果animation1和animation2 。最后,状态机进入需要有一个初始状态,我们可以设定state1为我们这个状态机的初始态。
有了状态机的描述图,我们就可以看看用Qt-4.6的代码,如何实现以上功能。
创建状态机
QStateMachine *machine = new QStateMachine;
创建两个状态,状态的属性由一个QPushButton的位置大小决定。
-
- [font=verdana, geneva, arial, helvetica, sans-serif][font=mceinline]QPushButton *button = new QPushButton(“Animated Button”);
- QState *state1 = new QState(machine);
- state1->assignProperty(button, “geometry”, QRect(0, 0, 150, 30));
- QState *state2 = new QState(machine);
-
- state2->assignProperty(button, “geometry”, QRect(250, 250, 150, 30));[/font][/font]
将状态1设置为状态机的初始状态
machine->setInitialState(state1);
增加触发状态1到状态2的触发条件,QPushButton按钮被按下,动画效果由addAnimation()完成
QSignalTransition *transition1 = state1->addTransition(button,SIGNAL(clicked()), state2);
transition1->addAnimation(new QPropertyAnimation(button, “geometry”));
细心的读者可能发现QPropertyAnimation的setStartValue()和setEndValue()都没有被调用到。其实这里动画变化的初始态和结束态,由state1和state2决定的。另外,如果没有设置动画的持续时长,则默认是250毫秒。
同理,增加状态2到状态1的触发条件,也是按钮被按下
-
- QSignalTransition *transition2 = state2->addTransition(button,SIGNAL(clicked()), state1);
-
- transition2->addAnimation(new QPropertyAnimation(button, “geometry”));
最后一步,将状态机启动即可,是不是很简单?
machine->start();
完整代码在下头
-
- #include <QApplication>
- #include <QPushButton>
- #include <QStateMachine>
- #include <QState>
- #include <QSignalTransition>
- #include <QPropertyAnimation>
- int main(int argc,char *argv[]){
- QApplication app(argc,argv);
- QPushButton *button = new QPushButton(“Animated Button”);
- button->show();
- QStateMachine *machine = new QStateMachine;
- //QState *state1 = new QState(machine->rootState());
- QState *state1 = new QState(machine);
- state1->assignProperty(button, “geometry”, QRect(0, 0, 150, 30));
- machine->setInitialState(state1);
- //QState *state2 = new QState(machine->rootState());
- QState *state2 = new QState(machine);
- state2->assignProperty(button, “geometry”, QRect(250, 250, 150, 30));
- QSignalTransition *transition1 = state1->addTransition(button,
- SIGNAL(clicked()), state2);
- transition1->addAnimation(new QPropertyAnimation(button, “geometry”));
- QSignalTransition *transition2 = state2->addTransition(button,
- SIGNAL(clicked()), state1);
- transition2->addAnimation(new QPropertyAnimation(button, “geometry”));
- machine->start();
- app.exec();
-
- }