首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有动画的QStateMachine事件循环

带有动画的QStateMachine事件循环
EN

Stack Overflow用户
提问于 2017-03-08 21:43:21
回答 1查看 402关注 0票数 1

我想用QStateMachine创建一个没完没了的循环,其中我也需要动画。

代码语言:javascript
复制
QColor leastTransparent, mostTransparent = color();
leastTransparent.setAlpha(250);
mostTransparent.setAlpha(150);

QState *s1 = new QState();
s1->assignProperty(this, "color", leastTransparent);

QState *s2 = new QState();
s2->assignProperty(this, "color", mostTransparent);

QSignalTransition *transition =  s1->addTransition( this, SIGNAL(triggerSignal()),s2);
QSignalTransition *transition2 = s2->addTransition(s2, SIGNAL(entered),s1);

QPropertyAnimation* animation = new QPropertyAnimation( this, "color");
animation->setDuration( 5000 );
transition->addAnimation(animation);

QPropertyAnimation* animation2 = new QPropertyAnimation( this, "color");
animation2->setDuration(10000);
transition2->addAnimation(animation2);

m_stateMachineAnimation->addState(s1);
m_stateMachineAnimation->addState(s2);
m_stateMachineAnimation->setInitialState(s1);
m_stateMachineAnimation->setGlobalRestorePolicy(QStateMachine::RestoreProperties);
m_stateMachineAnimation->start();

我希望这里的颜色在"triggerSignal“之后的前5秒会变得更加不透明。州将是"s2“。并且超过"s2“的进入信号被触发,它将获得越来越多的透明度在10秒内。

但是,我现在有s2触发器,而不需要在"triggerSignal“之后等待5秒,而不是立即触发s1,而不需要等待10秒。

为什么QStateMachine没有考虑到我的持续时间。如何使用QStateMachine实现这样的动画?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-08 22:33:30

你似乎希望动画能创造出某种介于两者之间的状态。它不会做这样的事。这种转变只会触发动画。您立即从s2过渡到s1,没有时间完成动画。相反,在设置属性的最终值时,需要显式地触发后续的转换。QState::propertiesAssigned信号在这方面是最有用的。或者,您可以使用动画的finished()信号。

在下面的示例中,单击窗口内启动动画循环:

代码语言:javascript
复制
// https://github.com/KubaO/stackoverflown/tree/master/questions/statemachine-animation-42682462
#include <QtWidgets>

const char kColor[] = "color";
class Widget : public QWidget {
   Q_OBJECT
   Q_PROPERTY(QColor color MEMBER m_color NOTIFY colorChanged)
   QColor m_color{Qt::blue};
   QStateMachine m_machine{this};
   QState s0{&m_machine}, s1{&m_machine}, s2{&m_machine};
   QEventTransition t01{this, QEvent::MouseButtonPress};
   QPropertyAnimation anim_s1{this, kColor}, anim_s2{this, kColor};
   void paintEvent(QPaintEvent *) override {
      QPainter{this}.fillRect(rect(), m_color);
   }
   Q_SIGNAL void colorChanged(const QColor &);
public:
   Widget() {
      connect(this, &Widget::colorChanged, [this]{ update(); });
      s1.assignProperty(this, kColor, QColor{Qt::red});
      s2.assignProperty(this, kColor, QColor{Qt::green});

      t01.setTargetState(&s1);
      s0.addTransition(&t01);                              t01.addAnimation(&anim_s1);
      s1.addTransition(&s1, &QState::propertiesAssigned, &s2)->addAnimation(&anim_s2);
      s2.addTransition(&s2, &QState::propertiesAssigned, &s1)->addAnimation(&anim_s1);

      anim_s1.setDuration(1000);
      anim_s2.setDuration(2000);

      m_machine.setInitialState(&s0);
      m_machine.start();
   }
};

int main(int argc, char ** argv) {
   QApplication app{argc, argv};
   Widget w;
   w.setFixedSize(300, 200);
   w.show();
   return app.exec();
}
#include "main.moc"

顺便说一下,这说明动画插入了RGB值,使redblue之间的颜色在从(1,0,0)(.5,.5,0)(0,1,0)之间变暗。对于人类的消费来说,插值HSV会更有意义,这样就可以保持不变的值(亮度),只有色调(我们人类真正称之为“颜色”)才会改变。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42682462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档