您的位置:首页 > 编程语言 > Qt开发

【Qt】

2015-12-04 15:15 477 查看
Qt动画中常常和状态机相互练习,那么什么是状态机呢?

网上的一些解释太高端了,不是很亲民。。。

状态机:

回想之前的动画,运行之后就开始在桌面上运动。那么有什么方法能够控制这一点呢?

比如,按下button之后,动画才出现;

我想:信号和槽应该是一种想法。。。

那么,类似于这种机制,也就是状态机啦。

例如,按钮1处于状态1下是静止的,clicked(),就切换到了状态2,这时是运转的。。。

一 状态机框架中的一些类

就看看吧,熟悉熟悉。。。

QAbstractState

QAbstractTransition

QEventTransition

QFinalState

QHistoryState

QKeyEventTransition

QMouseEventTransition

QSignalTransition

QState

QStateMachine

QStateMachine::SignalEvent

QStateMachine::WrappedEvent

二 状态机机制原理

2.1 第一步:创建状态机

注意:QStateMachine 和 QState

//new 状态机
QStateMachine *machine = new QStateMachine;
// new 状态1
QState *state1 = new QState(machine);
// new 状态2
QState *state2 = new QState(machine);


2.2 第二步:把状态和当前的属性绑定

注意:state.assignProperty()

state1->assignProperty(button, "geometry", QRect(0, 0, 150, 30));
//状态1  ——  位置1
state2->assignProperty(button, "geometry", QRect(250, 250, 150, 30));
//状态2  ——  位置2


2.3 第三步:状态转换

注意:

QSignalTransition

.addTransition //状态转换如s1->s2,触发方式

.addAnimation //状态转换的时候添加一些动画

//状态转换 state1 -> state2
QSignalTransition *transition1 = state1->addTransition(button,SIGNAL(clicked()), state2);
transition1->addAnimation(new QPropertyAnimation(button, "geometry"));

//状态转换 state2 -> state1
QSignalTransition *transition2 = state2->addTransition(button,SIGNAL(clicked()), state1);
transition2->addAnimation(new QPropertyAnimation(button, "geometry"));


2.4 总体框图就是。。。

状态1  |   属性1        《-----》           状态2  |   属性2
||||||
这里可以添加一些动画


(1)绑定 状态 | 属性

state1->assignProperty(button, “geometry”, QRect(0, 0, 150, 30));

(2)哪个状态 转换到 哪个状态

QSignalTransition *transition1 = state1->addTransition(button,SIGNAL(clicked()), state2);

(3)状态转换可以添加一些动画

transition1->addAnimation(new QPropertyAnimation(button, “geometry”));

三 例子

1、窗口动画—升级版4

int main(int argc,char *argv[])
{
QApplication app(argc,argv);

//new button
QPushButton *button = new QPushButton("Animated Button");
button->show();

//new 状态机
QStateMachine *machine = new QStateMachine;

// new 状态1
QState *state1 = new QState(machine);
state1->assignProperty(button, "geometry", QRect(0, 0, 150, 30));
machine->setInitialState(state1);       //初始化当前状态为state1

// new 状态2
QState *state2 = new QState(machine);
state2->assignProperty(button, "geometry", QRect(250, 250, 150, 30));

//状态转换 state1 -> state2
QSignalTransition *transition1 = state1->addTransition(button,SIGNAL(clicked()), state2);
transition1->addAnimation(new QPropertyAnimation(button, "geometry"));

//状态转换 state2 -> state1
QSignalTransition *transition2 = state2->addTransition(button,SIGNAL(clicked()), state1);
transition2->addAnimation(new QPropertyAnimation(button, "geometry"));

machine->start();

app.exec();
}


2、状态转换窗口(一些常用代码以及小技巧)

int main(int argc, char* argv[])
{
QApplication app(argc,argv);
QStateMachine sMachine;//一个状态机对象
QState s;//和fState在同一个层次
QState s1;//3个状态对象
s1.setParent(&s);
QState s2;
s2.setParent(&s);
QState s3;
s3.setParent(&s);
s.setInitialState(&s1);//一组状态中要指定一组状态中的初始状态
QFinalState fState;

QWidget w;
QHBoxLayout layout;
QPushButton button;
QPushButton qButton;
layout.addWidget(&button);
layout.addWidget(&qButton);

w.setLayout(&layout);

//给每个状态添加过渡
s.addTransition(&qButton,SIGNAL(clicked()),&fState);//s -- > finalState,但是在这组内的状态对于这个过渡可以覆盖

//s2.addTransition(&qButton,SIGNAL(clicked()),&s3);//如果添加这一个句,那么在s2点击qButton按钮
//就不会退出,只是转向了s3

s1.addTransition(&button,SIGNAL(clicked()),&s2);//s1为这个过渡的始状态,s2为末状态
s2.addTransition(&button,SIGNAL(clicked()),&s3);
s3.addTransition(&button,SIGNAL(clicked()),&s1);
//每个状态进入时,设置指定对象指定项指定的值
s1.assignProperty(&button,"text","s1-->s2");
s2.assignProperty(&button,"text","s2-->s3");
s3.assignProperty(&button,"text","s3-->s1");

//在状态转换的出入口做有效率的工作
//原理:
//当进入某个状态的时候,就会发出QState::entered()信号
//当离开某个状态的时候,就会发出QState::exited()信号
//自定义装的时候可以重写QAbstractState::onEntry()和QAbstractState::onExit()

QObject::connect(&s3,SIGNAL(entered()),&w,SLOT(showMinimized()));
//进入s3状态,窗口最大化
QObject::connect(&s3,SIGNAL(exited()),&w,SLOT(showMaximized()));
//离开s3状态,窗口最小化

sMachine.addState(&s);//对于状态机只是添加顶层的状态
// sMachine.add
a97c
State(&s1);
// sMachine.addState(&s2);
// sMachine.addState(&s3);
sMachine.addState(&fState);

QObject::connect(&sMachine,SIGNAL(finished()),&app,SLOT(quit()));
//设置状态机的初始状态
//sMachine.setInitialState(&s1);
sMachine.setInitialState(&s);//对于状态机的初始化,只是使用顶层的状态初始化,所以每个顶层如果是
//一组状态,那么就要指定这组状态的初始化状态
w.show();
//状态机开启
sMachine.start();

//可以通过给状态分组来实现状态过渡的共享,比如我们希望在任何状态下我们都能够退出,
//那么这个退出状态就是比其他的状态具有高的状态层次,那么我们就要将其他的状态封装在
//合适的与退出状态同层次的一个高阶的状态层次中
return app.exec();
}


四、状态机制的一些运用

4.1 QState::entered() 和 QAbstractState::onExit()

//在状态转换的出入口做有效率的工作
//原理:
//当进入某个状态的时候,就会发出QState::entered()信号
//当离开某个状态的时候,就会发出QState::exited()信号
//自定义装的时候可以重写QAbstractState::onEntry()和QAbstractState::onExit()

QObject::connect(&s3,SIGNAL(entered()),&w,SLOT(showMinimized()));
//进入s3状态,窗口最大化
QObject::connect(&s3,SIGNAL(exited()),&w,SLOT(showMaximized()));
//离开s3状态,窗口最小化
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: