如何动画QBrush的颜色

时间:2014-08-26 20:43:23

标签: 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&);
    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();

但它不起作用,没有任何反应,画笔的颜色与以前相同。我该怎么做才能解决它?

2 个答案:

答案 0 :(得分:3)

您必须提供自己的实现以在QBrush类型上进行插值。 来自Qt的文档:

QPropertyAnimation在Qt属性上进行插值。当属性值存储在QVariants中时,该类继承QVariantAnimation,并支持与其超类相同的变体类型的动画。” (http://qt-project.org/doc/qt-4.8/qpropertyanimation.html

请参阅“详细说明”部分中的支持类型列表以及如何实现自定义插值的示例: http://qt-project.org/doc/qt-4.8/qvariantanimation.html

另一种方法是仅在QColors之间进行插值,然后更新画笔:

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

答案 1 :(得分:3)

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

这会在颜色中执行转换,但也会在转换过程中途改变模式。

然后,这将是您的代码中这种转换的虚拟应用程序:

QBrush

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