【问题标题】:How to animate color of QBrush如何为 QBrush 的颜色设置动画
【发布时间】:2014-10-20 07:25:49
【问题描述】:

我想为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();

但它不起作用,没有任何反应,刷子的颜色和以前一样。我应该怎么做才能解决它?

【问题讨论】:

  • 最后有一个。
  • 当我发表评论时没有?,编辑修复了它。看起来更好。

标签: c++ qt qproperty qpropertyanimation


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您必须提供自己的实现,以便在 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();
    

    【讨论】:

    • 如果你谈到这个 QVariant myColorInterpolator(const QColor &start, const QColor &end, qreal progress) { ... return QColor(...); } ... qRegisterAnimationInterpolator(myColorInterpolator);我真的不明白它是什么以及如何使用它。我在哪里可以读到它?而且我什至不明白为什么我的方法不起作用
    • 您必须将“QColor”替换为您要使用的类型。如果您不想这样做,您也可以仅在 QColor 之间进行插值。我编辑了我的答案来讨论这个问题。希望对你有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多