C++ 如何设置QBrush颜色的动画

C++ 如何设置QBrush颜色的动画,c++,qt,qproperty,qpropertyanimation,C++,Qt,Qproperty,Qpropertyanimation,我想为QBrush的颜色设置动画。有关更多详细信息,请参阅下面的代码 那是我的.h文件 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&); Cel

我想为
QBrush
的颜色设置动画。有关更多详细信息,请参阅下面的代码

那是我的.h文件

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); //конструктор
}
那是我的.cpp文件

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);
}
这就是动画:

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();
QPropertyAnimation* animation = new QPropertyAnimation(selectedCell, "color");
animation->setDuration(10000);
animation->setStartValue(QColor(255,0,0));
animation->setEndValue(QColor(0,255,0));
animation->start();

但它不起作用,什么也没发生,画笔的颜色和以前一样。我应该怎么做才能修复它?

您必须提供自己的QBrush类型插值实现。 从Qt的文档:

QPropertyAnimation在Qt属性上插值。由于属性值存储在QVariantAnimation中,该类继承QVariantAnimation,并支持与其超类相同的变量类型的动画 ()

请参见“详细说明”部分中的支持类型列表和如何实现自定义插值的示例:

另一种方法是仅在QColor之间插值,然后更新笔刷:

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;
};
带动画:

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();
QPropertyAnimation* animation = new QPropertyAnimation(selectedCell, "color");
animation->setDuration(10000);
animation->setStartValue(QColor(255,0,0));
animation->setEndValue(QColor(0,255,0));
animation->start();

QT不知道如何在开始
QBrush
和结束
QBrush
之间执行转换
QBrush
具有比颜色更多的属性,您可以设想一个颜色保持不变且只有图案变化的动画。因此,这种转换没有默认支持。 正如@fscibe所暗示的,您可以编写自己的方法来执行转换,在该转换中,您可以指定如何从一个
QBrush
转换到另一个

粗略的例子:

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  );


}
这将在颜色中执行过渡,但也会在过渡的中途更改图案

然后,在您的代码中有一个此转换的虚拟应用程序:

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();
}
int main(int argc,char**argv)
{
QApplication应用程序(argc、argv);
QGraphicsView*视图=新的QGraphicsView;
Qgraphicscene*场景=新的Qgraphicscene;
QDialog*dialog=新建QDialog;
QGridLayout*layout=新的QGridLayout;
布局->添加小部件(视图);
查看->设置场景(场景);
场景->设置场景设置(-500,-50010001000);
对话框->设置布局(布局);
对话框->显示();
Cell*selectedCell=新单元格;
场景->添加项(选定单元格);
qRegisterAnimationInterpolator(霉色素Interpolator);
QPropertyAnimation*动画=新的QPropertyAnimation(选择的单元格,“笔刷”);
动画->设置持续时间(10000);
动画->设置起始值(QBrush(Qt::blue));
动画->setEndValue(QBrush(Qt::红色));
动画->开始();
返回app.exec();
}

显然,这是一个虚构的例子,对于颜色变化,正如你从fscibe答案中看到的,它正在重新发明轮子,但这是为了向你展示,定义自己的过渡方法,例如
QBrush
,你可以做的不仅仅是简单地改变颜色。

最后有一个。当我发表评论时,没有
,编辑修正了它。看起来更好。如果您谈论这个QVariant mycolor interpolator(const QColor&start,const QColor&end,qreal progress){…返回QColor(…);}。。。qRegisterAnimationInterpolator(霉色素Interpolator);我真的不明白它是什么,我如何使用它。我在哪里可以读到它?我甚至不明白为什么我的方法不起作用。你必须用你想要使用的类型替换“QColor”。如果不想这样做,也可以仅在QColor之间插值。我编辑了我的答案来谈论这个问题。我希望它能帮助你。