3

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

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

4

2 回答 2

4

QT 不知道如何在开始QBrush和结束之间执行转换QBrushQBrush除了颜色之外,还有更多属性,您可以设想一个动画,其中颜色保持不变,只有图案发生变化。因此,这种转换没有默认支持。正如@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,您可以做的不仅仅是更改颜色。

于 2014-08-27T07:39:14.193 回答
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();
于 2014-08-26T21:28:59.183 回答