How to animate color of QBrush

元气小坏坏 提交于 2019-12-06 07:36:39

问题


I want to animate Color of QBrush. For more details see code below

That's my .h file

class Cell : public QObject, public QGraphicsRectItem
{
    Q_OBJECT
    Q_PROPERTY(QBrush brush READ brush WRITE set_Brush)
public:
    QBrush _brush() const;
    void set_Brush(const QBrush&);
    Cell(QGraphicsItem *parent = 0); //конструктор
}

That's my .cpp file

Cell::Cell(QGraphicsItem *parent)
    : QObject(), QGraphicsRectItem(parent) 
{
    this->setRect(0, 0, Scale, Scale); 
}

QBrush Cell::_brush() const
{
    return this->brush();
}

void Cell::set_Brush(const QBrush & brush)
{
    this->setBrush(brush);
}

and that's animation:

QPropertyAnimation* animation = new QPropertyAnimation(selectedCell, "brush");
animation->setDuration(10000);
animation->setStartValue(QBrush(QColor(255,0,0)));
animation->setEndValue(QBrush(QColor(0,255,0)));
animation->start();

But it doesn't work, nothing happens, color of brush is the same that was before. What should I do to fix it?


回答1:


QT does not know how to perform a transition between the start QBrush and the end QBrush. QBrush has more properties than just color, you could envisage an animation where the color stays the same and only the pattern changes. Thus there is no default support for this kind of transition. As @fscibe hinted, you can write your own method to perform a transition in which you specify how you want to transition from one QBrush to the other.

Crude example:

QVariant myColorInterpolator(const QBrush &start, const QBrush &end, qreal progress)
{
  QColor cstart = start.color();
  QColor cend = end.color();
  int sh = cstart.hsvHue();
  int eh = cend.hsvHue();
  int ss = cstart.hsvSaturation();
  int es = cend.hsvSaturation();
  int sv = cstart.value();
  int ev = cend.value();
  int hr = qAbs( sh - eh );
  int sr = qAbs( ss - es );
  int vr = qAbs( sv - ev );
  int dirh =  sh > eh ? -1 : 1;
  int dirs =  ss > es ? -1 : 1;
  int dirv =  sv > ev ? -1 : 1;

  return QBrush(QColor::fromHsv( sh + dirh * progress * hr,
                             ss + dirs * progress * sr,
                             sv + dirv * progress * vr), progress > 0.5 ? Qt::SolidPattern : Qt::Dense6Pattern  );


}

this performs a transition in the colors but also changes the pattern halfway through the transition.

Then here would be a dummy application of this transition in your code:

int main(int argc, char** argv)
{
  QApplication app(argc,argv);
  QGraphicsView *view = new QGraphicsView;
  QGraphicsScene *scene = new QGraphicsScene;
  QDialog *dialog = new QDialog;
  QGridLayout *layout = new QGridLayout;
  layout->addWidget(view);
  view->setScene(scene);
  scene->setSceneRect(-500,-500,1000,1000);
  dialog->setLayout(layout);
  dialog->show();

  Cell *selectedCell = new Cell;
  scene->addItem(selectedCell);

  qRegisterAnimationInterpolator<QBrush>(myColorInterpolator);
  QPropertyAnimation* animation = new QPropertyAnimation(selectedCell, "brush");
  animation->setDuration(10000);
  animation->setStartValue(QBrush(Qt::blue));
  animation->setEndValue(QBrush(Qt::red));
  animation->start();

  return app.exec();
}

Obviously this is dummy example and for the color change it is re-inventing the wheel as you see from fscibe answer, but this is to show you that defining your own transition method for e.g. QBrush you can do more than simply change the color.




回答2:


You must provide your own implementation for interpolating on QBrush type. From Qt's doc:

"QPropertyAnimation interpolates over Qt properties. As property values are stored in QVariants, the class inherits QVariantAnimation, and supports animation of the same variant types as its super class." (http://qt-project.org/doc/qt-4.8/qpropertyanimation.html)

See the list of supported types and an example of how to implement a custom interpolation here in the "Detailed Description" section: http://qt-project.org/doc/qt-4.8/qvariantanimation.html

An alternative would be to interpolate between QColors only, and then update your brush:

class Cell : public QObject, public QGraphicsRectItem
{
    Q_OBJECT
    Q_PROPERTY(QColor color READ _color WRITE set_Color)
public:
    Cell()
    {
        setRect(0,0,100,100); // non-zero rect
        m_brush.setStyle(Qt::SolidPattern); // fill color is active
    }

    QColor _color() const
    {
        return brush().color();
    }
    void set_Color(const QColor& c)
    {
        m_brush.setColor(c);
        setBrush( m_brush );
    }

    QBrush m_brush;
};

With animation:

QPropertyAnimation* animation = new QPropertyAnimation(selectedCell, "color");
animation->setDuration(10000);
animation->setStartValue(QColor(255,0,0));
animation->setEndValue(QColor(0,255,0));
animation->start();


来源:https://stackoverflow.com/questions/25514812/how-to-animate-color-of-qbrush

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!